Rotation of 3pi inaccurate

Hello together,

I extended my 3Pi with a Ultrasonic device, with which I want to measure distances. Then I want to move to the nearest found obstacle.

In order to measure distances, the 3Pi should completely rotate once. At a specified angle, the robot is supposed to stop, perform the measurement and move to the next specified angle. However, I am having trouble with an exact rotation.

Here is the rotation code:

void rotate_degree(uint16_t degree){
	//Rotate left or right
	if(degree < 0) {
		set_motors(40, -40);
	} else {
		set_motors(-40, 40);
	}
	float multiplicator = degree / 360.0;
	//sleepTime360Degrees is the time the motors have to be turned on in order to make a full turn (based on the calibration)
	uint16_t sleepTime = sleepTime360Degrees * multiplicator;
	delay_ms(sleepTime);
	//Stop motors, when time is over
	set_motors(0,0);
}

Here, I set the motors to my desired speed and wait until the rotation of the specified degree is done. However, all my rotations are to short (~340° for 360°, ~75° for 90°…).

I perform a calibration when starting the robot. Here, I put the robot’s middle reflectance sensor over a small marker. Then, the robot rotates until its middle reflectance sensor is over the marker again and the time for a rotation is stopped. This is repeated 5 times. Lastly, I calculate the arithmetic mean of all elapsed times and store this result in sleepTime360Degrees.

I want to use the 3Pi on different surfaces, therefore, I think a calibration has to be done. However, I don’t know how to fix the problem with my non-exact rotations.

If needed, I can post my code for the calibration, but I think the calibration should be ok. Maybe there is a better way to perform the rotation itself?
I hope I was able to make my problem clear and that you can help me here! Thank you!

Sincerely,
centershock

Hello.

I suspect the problem is that your calibration code is not properly accounting for the extra time it takes to get up to speed, which results in an average time that is a little too short. In general, performing precise rotations is not easy without feedback. I think you might have better results just using trial-and-error to determine the ideal duration to produce a 360° turn. You might also come up with separate durations for 90°, 180°, and 270° and interpolate between them to figure out the best duration for arbitrary turns.

Also, using floats is pretty slow on an 8-bit AVR and takes up a lot of flash, and the way you are using them can easily be replaced by integer math.

- Ben