Land Robot moving in straight line. PID, IMU.

Hello guys.
I have a slightly complex question which I have been trying to figure out for months. I'm not looking for a direct answer but instead perhaps some better reading that would have examples. I have build a small robot with the Arduino and expansion sensor board. Now, I've been reading that if I want to get my robot to travel in a straight line I would have to have implement a PID strategy or I could use a IMU with a kalman filter.
The issue that I'm running into, is that I have yet to find an example online that shows how to actually use this with a robot. In other words, I have 4 wheels on my robot. The pair move independently. I'm looking for an example of how to keep my robot on a straight line using these sensors as it relates to the adjustment of the wheels. Does anyone have any examples/guidance? I get feedback from the sensors but now I'm trying to make sense of that feedback as it relates to the wheels and speed.
I would greatly appreciate any guidance you guys can offer.

A gyro/accelerometer IMU isn't useful in your case, because you need a North reference for steering on the horizontal.

To steer straight, use wheel encoders and two PID loops (one for each motor) to keep them rotating at the same speed, or use a magnetometer.

The latter option is actually quite easy to implement. You need to carefully calibrate the magnetometer in place, on your robot, so that the local iron and magnetic fields won't affect the steering. You may need to mount the magnetometer on a pole to get it far enough away, though. For an overview on calibration, see this blog entry.

Once you can get an accurate heading, steer in a straight line on a given heading (relative to due North), using a simple PID loop and differential steering. Increase the power to one motor and decrease it to the other to correct the heading.

Here is the PID loop used to steer a twin screw model boat using the above technique. It works VERY well.

 mag_heading = wrap360(v[0] + yaw_offset); //yaw = v[0], correct for magnetic North

// heading error and PID steering, "point_bearing" is the setpoint 

 error = heading_error(point_bearing, mag_heading);  //wrap to +/- 180 degrees
 
 //error is positive if current_heading > bearing (compass direction)
 //positive bias acts to reduce left motor speed, so bear left

 bias = (kp*error)/10;  //Kp in tenths (Kp=40;  Ki, Kd not necessary in water)

 // the motor routines internally limit the argument to {-255, 255}

 set_m1_speed(motorSpeed-bias); //left motor
 set_m2_speed(motorSpeed+bias); //right motor

Thanks jremington. I'll try to understand what you did here. quick question would there be any encoders that you would recommend?

Thanks again for the response.

No, I can't recommend any encoders, because I know nothing about your robot.

Hi,
Can you post a picture of your robot please, so we can see what motors you are using.
If it is the small yellow motor and gearbox, you can get an encoder addon.

https://brainy-bits.com/shop/modules/speed-sensor-module/

Tom... :slight_smile:


This is my robot. Thanks for the reply George.

Hi,
Sorry your pics did not take.

If use REPLY rather than QUICK REPLY and it has an attachment facility to attach your image files.

Tom... :slight_smile:

How do you decide which direction you want to travel?

Oops sorry for the noob mistake.

IMG_2629_1.png

johnwasser:
How do you decide which direction you want to travel?

I was hoping to use the IMU to identify direction. But I have to figure out how to go straight before direction. :smiley:

Hi,
It looks like they are the motor gearbox I showed, do your units have a bit of output shaft out both sides of the gearbox?

Tom... :slight_smile:

miguel83:
I was hoping to use the IMU to identify direction. But I have to figure out how to go straight before direction. :smiley:

Unless your IMU has a magnetometer you are not going to get a heading out of it. The gyroscope will give you rate of change of heading but after you integrate them over time to het change in heading they will drift too much to be of use.
If you are moving over large distances outdoors you can probably use a GPS to get heading information but for short distances or indoor use you really need a compass/magnetometer.

TomGeorge:
Hi,
It looks like they are the motor gearbox I showed, do your units have a bit of output shaft out both sides of the gearbox?

Tom... :slight_smile:

TomGeorge,
yes it does. The only thing I know need to understand is how this little piece of carboard is an encoder. In other words how do I read the values to keep my robot moving in a straight line. Do you have any examples i can follow. I really appreciate all your replies.

Miguel :slight_smile:

johnwasser:
Unless your IMU has a magnetometer you are not going to get a heading out of it. The gyroscope will give you rate of change of heading but after you integrate them over time to het change in heading they will drift too much to be of use.
If you are moving over large distances outdoors you can probably use a GPS to get heading information but for short distances or indoor use you really need a compass/magnetometer.

johnwasser
Thanks again. The IMU that I have is this one

it contains
ITG-3200 (MEMS triple-axis gyro), ADXL345 (triple-axis accelerometer), and HMC5883L (triple-axis magnetometer) - to give you nine degrees of inertial measurement.
Though i can connect the sensor to my robot I'm trying to figuere out how to convert its output into something meanignful to help me drive my robot. Once again, truly appreciate all the guidance you guys have offered thus far.

Have you been able to get a heading from the magnetometer? You can use the accelerometer for tilt compensation (compass not horizontal). Once you can get a heading you can keep that heading by adjusting the relative speed of the two motors. For best effect you can use the PID library to implement a PID control loop. The "Setpoint" of the PID would be the desired heading. The "Input" would be the current compass heading (in the same units as Setpoint, probably degrees), and the "Output" will be a control value whose range you can set. If you set the range to something like +/-64 then you can set the speed of the left motor to something like BaseSpeed+Output and the right motor to BaseSpeed-Output. If Output is a positive number the left motor will go faster and the car will turn right. If the Output is negative the left motor will turn slower and the car will turn left.

Once you can get a heading you can keep that heading by adjusting the relative speed of the two motors.

Exactly as described, and coded, in reply #1!

Hi,
This may help with PID controlling your motors.

You first need to understand how PID works.

Tom... :slight_smile:

TomGeorge:
Hi,
This may help with PID controlling your motors.

Arduino PID Motor Controller | RobotShop Community

PID control implemented on DC motor with Arduino – Enhancing knowledge in control systems theories and its applications in the real world.

You first need to understand how PID works.

Tom... :slight_smile:

TomGeorge
Thanks again for all your responses. Since I have 4 wheels, do you think I will need 4 sensors? one for each wheel. Sorry if the question sounds stupid but I'm just trying to make sure I understand what the hell I'm doing :-).

jremington:
Exactly as described, and coded, in reply #1!

jremington
Thanks for the reply. Unfortunately for me, I'm still an amateur. You article is very good, but I'm afraid is going over my head at the moment. I have 4 wheels in a robot and I'm trying to move in a straight line. My problem is a simple as that, but quite difficult for me. Thanks for your patience and again thanks for response.

This is my robot that uses PID for balance and to turn exactly 90 degrees every 2 seconds
I will post the code for you in the morning :slight_smile:
In the mean time enjoy the short video. Watch how it forces the turn even when it runs into stuff