Hi,
Integration is a pain. If you rely solely on integration you will always experience drift. However there are some ways to minimize drift.
Offset
First the offset (a0 in your program). You should calculate this on several readings, not just one. This is to cancel out noise in the measurement. The offset value should also be a float instead of an integer otherwise it may not be exact and an error in the offset will build up quickly in velocity. Also the velocity should be a float. I understand you already did this and that this improved things.
Timing
If accurate timing is an issue (I don't think so) I would calculate deltaT independently from the sleep timing. Here is an example.
- Code: Select all
long now;
long lastTime=System.nanoTime();
while (true) {
long now=System.nanoTime();
if (lastTime==0) lastTime=now;
double dt=(now-lastTime)*Math.pow(10,-9);
lastTime=now;
Thread.sleep(20);
Sensor mounting
I would not assume that your sensor is level, you might think it is, as you correct for offset and therefore get zero acceleration at stand still. However, if there is an alignment error on the sensor then the calculated offset is not the true offset but the sum off the true offset and the alignment error.
But even if the sensor would be perfectly level at stand still this doesn't mean that it remains level when your robot is accelerating or moving. Inertia of the robot and motors and friction in the drive system will tilt your robot. If you want to know if this is an issue you should keep track of the Z-acceleration. If it is no longer exactly 1 G when moving/accelerating then you know your robot tilts during movement. It will be very hard to correct for this in code as you cannot really distinguish tilt from acceleration.
Some tips.
Try to use proper units for acceleration, time and speed. Convert if needed. This will help to understand better what is happening and how big your problem is.
The NXTChartingLogger is a great tool to examine your sensors.
You can increase the query speed of sensor readings ( up to 1.4 ms instead of 10 ms) by adding this line of code before you instantiate the sensor.
- Code: Select all
SensorPort.S1.i2cEnable(I2CPort.HIGH_SPEED);