Car not moving in a straight path

Hi,

I'm building this project where I have to move a car in a straight path for a certain distance at regular intervals. The issue I'm facing is that that car is not moving in a straight path. This is the code I have:

void Compass_Forward()                                               
{            
  while (blueToothVal == 9)                                           // Go forward until Bluetooth 'Stop' command is sent

                                                         
   {  
    getCompass();                                                     // Update Compass Heading
    bluetooth();                                                      // Check to see if any Bluetooth commands have been sent
    if (blueToothVal == 5) {break;}                                   // If a Stop Bluetooth command ('5') is received then break from the Loop
    
    if ( abs(desired_heading - compass_heading) <= compass_dev )      // If the Desired Heading and the Compass Heading are within the compass deviation, X degrees of each other then Go Forward
                                                                      // otherwise find the shortest turn radius and turn left or right  
       {
         Forward(); 
          
       } else 
         {    
            int x = (desired_heading - 359);                          // x = the GPS desired heading - 360
            int y = (compass_heading - (x));                          // y = the Compass heading - x
            int z = (y - 360);                                        // z = y - 360
                     
            if ((z <= 180) && (z >= 0))                               // if z is less than 180 and not a negative value then turn left 
            {                                                         // otherwise turn right
              SlowLeftTurn();
                        
            }
            else
            {
              SlowRightTurn();
              
            }              
        } 
 }                                                                   // End While Loop
}                                                                    // End Compass_Forward

and these are the functions that I'm calling

void getCompass()                                               // get latest compass value
 {  

  Vector norm = compass.readNormalize();

  // Calculate heading
  float heading = atan2(norm.YAxis, norm.XAxis);
 
  if(heading < 0)
     heading += 2 * M_PI;      
  compass_heading = (int)(heading * 180/M_PI);                   // assign compass calculation to variable (compass_heading) and convert to integer to remove decimal places                                                              

 }
void bluetooth()
{
 while (Serial1.available())                                    // Read bluetooth commands over Serial1 // Warning: If an error with Serial1 occurs, make sure Arduino Mega 2560 is Selected
 {  
  {  
      str = Serial1.readStringUntil('\n');                      // str is the temporary variable for storing the last sring sent over bluetooth from Android device
      //Serial.print(str);                                      // for testing purposes
  } 
    
    blueToothVal = (str.toInt());                               //  convert the string 'str' into an integer and assign it to blueToothVal
    Serial.print("BlueTooth Value ");
    Serial.println(blueToothVal);    

// **************************************************************************************************************************************************

 switch (blueToothVal) 
 {
            
        case 9:        
         Serial1.println("Compass Forward");
        setHeading();
        Compass_Forward();
        break;
    

 }
}
} 
// end of switch case
void SlowLeftTurn()
{
   
  motor1.setSpeed(175);                                                
  motor2.setSpeed(175);                      
  motor3.setSpeed(175);                       
  motor4.setSpeed(175);        
  
  motor1.run(BACKWARD);                         
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(BACKWARD);
}
void SlowRightTurn()
{
   
  motor1.setSpeed(175);                                                  
  motor2.setSpeed(175);                      
  motor3.setSpeed(175);                       
  motor4.setSpeed(175);         

  motor1.run(FORWARD);                                                           
  motor2.run(BACKWARD);
  motor3.run(BACKWARD);
  motor4.run(FORWARD);

and my compass deviation is 5

Just curious. Did it just start not moving in a straight line, or has it always had this problem? Does you code include using the IDE serial monitor to display values in your program?

Paul

Its always had this problem of not moving in a straight path. I'm using this car on grass (sports field), which deviates quite a lot to either right or left. I don't even know if this project is even feasible at this point. :slightly_frowning_face:

To your second question. Yes, my codes does display values in the serial monitor.

With those snippets of code, it has not chance of driving straight.

You did not show us the Forward() function. FIrst tune that one for any mis-match between your motors. You may find that it always drifts to one side. Make the other side drive at 245 instead of 255. Tune until it goes acceptably straight.

It looks like the "slow" left and right turns are turning in place, driving some motors forwards and some backwards. That will drive short segments kind-of straight before stopping to turn. To drive like a car drives, keep all motors going forwards but just slow down the ones on the side you want to turn towards. Maybe even make it proportional: the worse off course, the slower they go.

Question: Where is the compass located with respect to the motors and power leads? Any magnetic fields from the motor or the wiring could be causing bad readings from the compass. I'd log the compass output and see if it makes sense.

It would be interesting to disable the motor and move the car by hand while logging serial data to see how the data compares to the motor-enabled case.

Is there any plumbing under the field? Most worrisome is drainage plumbing. I tried the compass RC car thing once. It worked ok as a robot. Worked wonderful as a plumbing detector!

When debugging mine, I needed to get an idea what was going on in its crazed little robotic mind. I mounted a stick crosswise with 5 LEDs along it. these would light up if it thought it needed to go straight, right, left, hard right, hard left. This way, as it ran, you could get an idea what was going on in there.

-jim lee

Thanks for the replies, I'll keep them in mind. I have the compass at a high elevation away from any magnetic interference. The car that I've built can be seen in the attachments.

I thought about using PID controller instead of the compass for this project, this way I can make it move in a straight path for a certain distance. And later turn it about 90 degrees and repeat. But, im not sure if this method will work

You could mix the compass heading info in with a gyro. Let them both go at it and take a kind of average of the two.

-jim lee