# 3pi get line position

As I think that the readLine function adds some unecessary errors for the lineare loop back of the PID I have modified the code

``````int get_position(unsigned int *sensor_values, unsigned char readMode)
{
unsigned char i, on_line = 0;
int32_t avg; // this is for the weighted total, which is long
// before division
int sum; // this is for the denominator which is <= 32000
static int last_value=-2500; // assume initially that the line is left.
static int destvec= {-2500,-1000,0,1000,2500}; //respect the distance between the sensors

avg = 0;
sum = 0;

for(i=0;i<5;i++) {
int value = sensor_values[i];

// keep track of whether we see the line at all
if(value > 150) {
on_line += (1 <<i); //by that we know which sensor
}

// only average in values that are above a noise threshold
if(value > 50) {
avg += (int32_t)(value) * destvec[i];
sum += value;
}
}

if(!on_line)
{
play_frequency(800,250,14);
return last_value; //lets assume we do the right if we are blind
}

last_value = (avg/sum);
return last_value;
}
``````

the reason is simply that the sensors do not have the same distance to each other. so once the line reachs the outer sensors …error correction should get a much bigger value.

Additional I added the speed component to the PID. The idea behind that is simply that the distance between
2 measurements increases with the speed. In general it would be better to take the real distance between 2 measurements, but as there is no wheel encoder or other distance measurement …speed is not the worst.
Much better would be a calibrated motor and a timed sensor measurement.

and I renamed the function as readLine could easily mixed with read_line …but the purpose of that readLine is to get the line position.

works fine at full speed:
youtu.be/LJKvO9eZi6E

What i also want to add is a special lost line mode. I would slow down the motors or stop once a near field search
did not bring any success.

Hello, daubi.

I’m glad you are having success getting your 3pi to perform better.

I don’t understand this line:

``on_line += (2^i); //by that we know which sensor``

That line of code will have no effect if i==2. Is that what you wanted?

Maybe you really wanted this, which would make each bit in on_line correspond to a sensor:

``on_line |= (1 << i);``

–David

uppss …I should have checked c syntax …
yes …I wrote first 1 << i …but was not sure if I have to care about bit/byte ordering