I'm currently working on a line-following robot which uses three sensors to follow a black line. The sensors are pretty much in line and right next to each other.

Right now, I'm doing a simple line follow: if on the line go forward, otherwise turn left or right to regain the line. This means that the robot is wiggling along the line most of the time.

I'm looking for a better way for this robot to follow the line using three sensors. The program I'm writing is in Not eXactly C code. I'm trying to get the robot to utilize the power of PID control, but I'm not sure how one would go about writing a three-sensor PID line-follower program in NXC.

  • $\begingroup$ I'm looking for an answer that provides good, usable NXC code $\endgroup$ – shea Jan 18 '13 at 3:49

I dont use NXC, so I am hesitant to propose this as an answer, but I will comment that the sensors ARE linear - not binary. They measure dark, grey, and light - On, middle, off of line. You simply devise a scheme to get a unique #, and use that as the SetPoint to PID - works great. See Mindsensors light array for sample NXC code for their array. Adopt it to 3 sensors.

I don't know if this helps or not but is the scheme I use in RobotC; (higly shortened)

int LSA_GetAvg()
    char value[8];
    int som = 0;
    I2Cread(MINDSENSORS_LSA, LSA_ADDRESS, 0x42, value, 8);  // read 8 sensor values into an array
    int bits = 0;
    for (int i=0;i<8;i++)
        if (value[i] < 0x32)
        som += ((8-i)*10);
    return som / bits;

main loop {

    int avg = LSA_GetAvg();
    printf("avg %d\n", avg);

    if (avg != 0)
      steering = S3Pid(Oval, avg, 45, elapsedTime); // 45 is our goal, set point
      printf("Steer %d\n", steering);

      motor[LEFT] = clipBAD((basePower - steering), -100, 100);
      motor[RIGHT] = clipBAD((basePower + steering), -100, 100);
        // stuff gone wrong, we lost the line, check packed bits=0xff for a crossing


Edit: as I look at that OLD code - i see that is is not very optimum, and would work just fine with 3 binary sensors - just FYI.


I don't think traditional PID control is appropriate per se, since your sensors only provide a binary "is the line under me" signal; PID controls need to be able to calculate error (error = actual - desired). Also, you need motors that can adjust their speed instead of simply turning on and off.

One way to get PID control might be to increase the number of sensors from 3 to 9, with barely-overlapping sense area. That might get you a range of 17 values, 9 from sensors and 8 more in cases where 2 adjacent sensors are triggered. I'm not sure how many points you'll need to be able to measure in order for PID control to become effective.

A more abstract way to approach this would be to consider the wiggles-per-second to be the value controlled by the PID. In this case, the PID would control the maximum difference in speed between the two motors -- the maximum rate of turn. If your robot is wiggling to much, such a PID should cause it to turn in more gradual arcs. In this case, the correct target wiggles-per-second will depend on the radius of the tightest turn that the robot will have to make.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.