diff --git a/src/main.cpp b/src/main.cpp index 780b9c0..f47eefc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,116 +1,246 @@ #include #include #include "Adafruit_BNO08x_RVC.h" -#include -#include "Ultrasonic.h" +// #include // Commented out +// #include "Ultrasonic.h" // Commented out +#include "OmniWheelMotors.hpp" -PixyI2C pixy; +// Constants +#define MOTOR_SPEED 60 +#define ROTATION_ADJUSTMENT_SPEED 55 +#define SIGNAL_CLOSE_THRESHOLD 50 // Threshold for considering ball close (0 is closest, 255 is farthest) +#define SIGNAL_TIMEOUT 5000 // Time in ms to consider ball lost if no detection + +// Pin definitions for the motors +#define MOTOR1_R_PWM 3 +#define MOTOR1_L_PWM 5 +#define MOTOR2_R_PWM 6 +#define MOTOR2_L_PWM 9 +#define MOTOR3_R_PWM 10 +#define MOTOR3_L_PWM 11 + +// Sensor objects +// PixyI2C pixy; // Commented out Adafruit_BNO08x_RVC rvc = Adafruit_BNO08x_RVC(); -Ultrasonic uSensor1 = Ultrasonic(7); -Ultrasonic uSensor2 = Ultrasonic(10); -Ultrasonic uSensor3 = Ultrasonic(9); +// Ultrasonic uSensor1 = Ultrasonic(7); // Commented out +// Ultrasonic uSensor2 = Ultrasonic(10); // Commented out +// Ultrasonic uSensor3 = Ultrasonic(9); // Commented out -void setup() -{ - Wire.begin(); - pixy.init(); +// Motor control object +OmniWheelMotors motors(MOTOR1_R_PWM, MOTOR1_L_PWM, + MOTOR2_R_PWM, MOTOR2_L_PWM, + MOTOR3_R_PWM, MOTOR3_L_PWM); - // Wait for serial monitor to open +// Global variables +int lastBallSensor = -1; +int lastBallStrength = 255; // Start at max distance +unsigned long lastBallDetectionTime = 0; +bool ballLost = true; + +void setup() { + // Initialize serial communication Serial.begin(115200); - while (!Serial) + while (!Serial && millis() < 3000) // Wait up to 3 seconds for serial delay(10); - Serial1.begin(115200); // This is the baud rate specified by the datasheet - while (!Serial1) - delay(10); - - if (!rvc.begin(&Serial1)) - { // connect to the sensor over hardware serial - while (1) - delay(10); + Serial.println("ElBestia Robot Starting..."); + + // Initialize I2C + Wire.begin(); + + // Initialize IMU + Serial1.begin(115200); + if (!rvc.begin(&Serial1)) { + Serial.println("Failed to initialize IMU!"); + while (1) delay(10); } - // Print labels for the values - Serial.print(F("Yaw")); - Serial.print(F("\tPitch")); - Serial.print(F("\tRoll")); - Serial.print(F("\tX")); - Serial.print(F("\tY")); - Serial.println(F("\tZ")); + Serial.println("IMU initialized"); + + // Initialize motors + motors.begin(); + motors.setSpeedLimits(45, 70); // Set min and max speeds + motors.setRotationTime(2000); // Set time for full rotation (2 seconds = 360°) + Serial.println("Motors initialized"); + + // Brief motor test + motors.moveForward(MOTOR_SPEED); + delay(500); + motors.stop(); + delay(200); + + Serial.println("Initialization complete. Starting main loop."); } -void loop() -{ - // Get IMU data - Wire.requestFrom(0x10 / 2, 2); +void moveBasedOnSensor(int sensorNum, int strength) { + // Get current heading from IMU for reference BNO08x_RVC_Data heading; - static int i = 0; - uint16_t blocks; - char buf[32]; + if (rvc.read(&heading)) { + float yaw = heading.yaw; + Serial.print("Current Yaw: "); + Serial.println(yaw); + } + + // Calculate intensity for movement - closer means slower movement + // Invert the strength so 0 (close) becomes high intensity and 255 (far) becomes low + int moveIntensity = map(strength, 0, 255, MOTOR_SPEED, MOTOR_SPEED/2); + + // Maps the 12 sensors to movement directions + // North is 12, and we go clockwise (1, 2, 3...) + switch (sensorNum) { + case 12: // North - move forward + Serial.println("Moving forward (North)"); + motors.moveForward(moveIntensity); + break; + case 1: // North-northeast + Serial.println("Moving forward-right (NNE)"); + motors.moveForward(moveIntensity); + delay(200); + motors.moveRight(moveIntensity); + break; + case 2: // Northeast + Serial.println("Moving forward-right (NE)"); + motors.moveForward(moveIntensity/2); + motors.moveRight(moveIntensity); + break; + case 3: // East-northeast + Serial.println("Moving right (ENE)"); + motors.moveRight(moveIntensity); + break; + case 4: // East + Serial.println("Moving right (East)"); + motors.moveRight(moveIntensity); + break; + case 5: // East-southeast + Serial.println("Moving backward-right (ESE)"); + motors.moveRight(moveIntensity); + delay(200); + motors.moveBackward(moveIntensity/2); + break; + case 6: // Southeast + Serial.println("Moving backward-right (SE)"); + motors.moveBackward(moveIntensity/2); + motors.moveRight(moveIntensity); + break; + case 7: // South-southeast + Serial.println("Moving backward (SSE)"); + motors.moveBackward(moveIntensity); + break; + case 8: // South + Serial.println("Moving backward (South)"); + motors.moveBackward(moveIntensity); + break; + case 9: // South-southwest + Serial.println("Moving backward-left (SSW)"); + motors.moveBackward(moveIntensity); + delay(200); + motors.moveLeft(moveIntensity/2); + break; + case 10: // Southwest + Serial.println("Moving backward-left (SW)"); + motors.moveBackward(moveIntensity/2); + motors.moveLeft(moveIntensity); + break; + case 11: // West-southwest + Serial.println("Moving left (WSW)"); + motors.moveLeft(moveIntensity); + break; + default: + motors.stop(); + Serial.println("Unknown sensor direction, stopping"); + break; + } + + // Adjust movement duration based on signal strength + // Closer (lower value) = shorter movements + int moveDuration = map(strength, 0, 255, 200, 800); + delay(moveDuration); + motors.stop(); +} - while (rvc.read(&heading)) - { - int c = Wire.read(); // direction is the first byte - int strength = Wire.read(); - // Print IMU data - Serial.print("IMU - Direction: "); - Serial.print(c); - Serial.print(" Strength: "); +void trackBall() { + // Get IR ball direction from seeker (on I2C address 0x08) + Wire.requestFrom(0x08, 2); + + if (Wire.available() >= 2) { + int sensorNum = Wire.read(); // Sensor number (1-12) + int strength = Wire.read(); // Strength of the signal (0-255, 0 is closest) + + Serial.print("Ball - Sensor: "); + Serial.print(sensorNum); + Serial.print(", Strength: "); Serial.println(strength); - Serial.print("Heading: "); - Serial.print(heading.yaw); - Serial.print(","); - Serial.print(heading.pitch); - Serial.print(","); - Serial.print(heading.roll); - Serial.println(); - Serial.print("Acceleration: "); - Serial.print(heading.x_accel); - Serial.print(","); - Serial.print(heading.y_accel); - Serial.print(","); - Serial.print(heading.z_accel); - Serial.println(); - - // Get Ultrasonic sensor data - long uS1 = uSensor1.MeasureInCentimeters(); - Serial.print("Distance uS1: "); - Serial.print(uS1); - Serial.println(" cm"); - - long uS2 = uSensor2.MeasureInCentimeters(); - Serial.print("Distance uS2: "); - Serial.print(uS2); - Serial.println(" cm"); - - long uS3 = uSensor3.MeasureInCentimeters(); - Serial.print("Distance uS3: "); - Serial.print(uS3); - Serial.println(" cm"); - - // Get Pixy blocks - blocks = pixy.getBlocks(); - - if (blocks) - { - Serial.println("Detected blocks"); - i++; - // Print every 50 frames to avoid overwhelming serial - if (i % 50 == 0) - { - - // Print Pixy blocks - sprintf(buf, "Detected %d blocks:\n", blocks); - Serial.print(buf); - for (int j = 0; j < blocks; j++) - { - sprintf(buf, " block %d: ", j); - Serial.print(buf); - pixy.blocks[j].print(); - } - Serial.println(); + + // Only process if we have a valid sensor number + if (sensorNum >= 1 && sensorNum <= 12) { + lastBallSensor = sensorNum; + lastBallStrength = strength; + lastBallDetectionTime = millis(); + ballLost = false; + + // Move based on which sensor sees the ball + moveBasedOnSensor(sensorNum, strength); + } else { + Serial.println("Invalid sensor number from IR seeker"); + + // If signal is invalid, check if we lost the ball + if (millis() - lastBallDetectionTime > SIGNAL_TIMEOUT) { + ballLost = true; } - - delay(250); + } + } else { + Serial.println("No data available from IR seeker"); + + // Check if we've lost the ball for too long + if (millis() - lastBallDetectionTime > SIGNAL_TIMEOUT) { + ballLost = true; } } +} + +void searchForBall() { + Serial.println("Searching for ball..."); + + // If we previously detected the ball, turn toward that direction first + if (lastBallSensor != -1) { + // Use the last known direction to guide search + moveBasedOnSensor(lastBallSensor, 200); // Use medium strength value for searching + } else { + // Execute a search pattern - rotate slowly clockwise + // Use public methods instead of accessing private motor members + // This will rotate the robot clockwise to scan for the ball + motors.rotateToAngle(10); // Rotate a small amount (10 degrees) + + delay(300); // Short rotation + motors.stop(); + delay(300); // Pause to get sensor readings + } +} + +void loop() { + static unsigned long lastDebugPrint = 0; + + // Print debug info every second + if (millis() - lastDebugPrint > 1000) { + BNO08x_RVC_Data heading; + if (rvc.read(&heading)) { + Serial.print("IMU - Yaw: "); + Serial.print(heading.yaw); + Serial.print(", Pitch: "); + Serial.print(heading.pitch); + Serial.print(", Roll: "); + Serial.println(heading.roll); + } + + lastDebugPrint = millis(); + } + + // Ball tracking or searching + if (!ballLost) { + trackBall(); + } else { + searchForBall(); + } + + // Small delay to stabilize readings + delay(50); } \ No newline at end of file