Page 1 of 2

line follower (please help me)

Posted: 08 Dec 2011, 03:01
by dedeles
i'm a student of a college here in Philippines. i'm having my thesis with some colleagues. we are having trouble controlling the robot using the line follower. we just copied some codes and we add some. the robot should possess the capability of sorting objects(color-coded objects);
we want the robot to avoid obstruction as well; but we don't know how; we tried possible codes but it won't satisfy our requirements. what will i do??? can anybody help me??? i'm begging.. we're on the point of giving up; :(..

here's our code:

Code: Select all

#include "NXCDefs.h"
#include "NBCCommon.h"

#define MOTOR_LEFT      OUT_B
#define MOTOR_RIGHT     OUT_C
#define MOTOR_BOTH      OUT_BC
#define MOTOR_FORK      OUT_A
#define COLORSENSOR   SENSOR_2
#define TOUCH      SENSOR_3
#define ULSONIC      SensorUS(IN_1)
#define LIGHT_BLACK      115
#define LIGHT_WHITE      275

struct RGB {
   unsigned int red;
   unsigned int green;
   unsigned int blue;
};

RGB get_color(int sensorPort) {
   RGB color;
   color.red = ColorSensorValue(sensorPort, INPUT_RED);
   color.green = ColorSensorValue(sensorPort, INPUT_GREEN);
   color.blue = ColorSensorValue(sensorPort, INPUT_BLUE);
   return color;
}

unsigned int get_light(int sensorPort) {
   RGB color = get_color(sensorPort);
   float colorSum = color.red + color.green + color.blue;
   unsigned int light = colorSum / 3.0;
   return light;
}

sub follow_line() {
   
   float kP = 1.0; //6.0
   float kI = 0.0; //0.0001
   float kD = 0.0; //400

   
   float dT = 25;
   
   // Initialize the variables:
   int offset = LIGHT_WHITE - LIGHT_BLACK;
   int tP = 50;
   
   int proportional = 0;
   int integral = 0;
   int derivative = 0;
   
   int lastError = 0;
   
   while (2) {
      int lightValue = get_light(IN_2);
      int error = lightValue - offset;
      proportional = kP * error;
      integral = integral + error;
      derivative = (error - lastError) * dT;
      int output = proportional + kI * dT * integral + kD * derivative;
     
      int speedLeft = tP - output;
      int speedRight = tP + output;

   int value = 0;
     
      if (speedLeft > 100) {
         speedLeft = 100;
      } else if (speedLeft < -100) {
         speedLeft = -100;
      }
     
      if (speedRight > 100) {
         speedRight = 100;
      } else if (speedRight < -100) {
         speedRight = -100;
      }
     
      lastError = error;
   while(COLORSENSOR == INPUT_BLUECOLOR){
      Off(MOTOR_BOTH);
      while (ULSONIC == 32){
         PlayTone(330,400);
         OnFwdSync(OUT_BC, 50, 0); Wait(1000);
      }
      while (COLORSENSOR == INPUT_GREENCOLOR) {
         value = 1;
         Off(MOTOR_BOTH); Wait(100);
         while (ULSONIC == 24) {
             PlayTone(330, 400);
             OnRev(MOTOR_FORK, 100); Wait(2500);
             RotateMotor(MOTOR_BOTH, 50, 400);
             Off(MOTOR_BOTH);
              OnFwd(MOTOR_FORK, 100); Wait(2500);
             while (TOUCH == 1) {
            OnFwd(MOTOR_LEFT, 80);
            OnRev(MOTOR_RIGHT,80);
            Wait(999);
            break;
             }
         }
      }
      
      while (COLORSENSOR == INPUT_REDCOLOR) {
          Off(MOTOR_BOTH); Wait(100);
          while(ULSONIC == 24) {
              PlayTone(330, 400);
                   OnRev(MOTOR_FORK, 100); Wait(2500);
              RotateMotor(MOTOR_BOTH, 50, 400);
              Off(MOTOR_BOTH);
              OnFwd(MOTOR_FORK, 100); Wait(2500);
              while(TOUCH) {
            OnFwd(MOTOR_LEFT, 80);
            OnRev(MOTOR_RIGHT,80);
            Wait(900);
            break;
              }
              while(TOUCH == 0) {
            Off(MOTOR_BOTH);
              }
         }
      }    
      while (COLORSENSOR == INPUT_YELLOWCOLOR) {
          Off(MOTOR_BOTH); Wait(100);
          while(ULSONIC == 24) {
              PlayTone(330, 400);
                   OnRev(MOTOR_FORK, 100); Wait(2500);
              RotateMotor(MOTOR_BOTH, 50, 400);
              Off(MOTOR_BOTH);
              OnFwd(MOTOR_FORK, 100); Wait(2500);
              while(TOUCH) {
            OnFwd(MOTOR_LEFT, 80);
            OnRev(MOTOR_RIGHT,80);
            Wait(900);
            break;
              }
              while (TOUCH == 0){
            Off(MOTOR_BOTH);
              }
         }
      }    
   }

      OnFwd(MOTOR_LEFT, speedLeft);
      OnFwd(MOTOR_RIGHT, speedRight);
    }
   
}
void setup() {
   SetSensorColorFull(IN_2);
   SetSensorLowspeed(IN_1);
   SetSensorTouch(IN_3);
}
void grab(){
   OnFwd(MOTOR_FORK, 100);
   Wait(1000);
   Off(OUT_A);
}
sub not_touch(){
   while(!TOUCH){
      Off(MOTOR_BOTH);
   }
}
task main() {
   grab();
   setup();
   not_touch();
   follow_line();

}
please help us!!! have mercy..
we also want the robot to stop when it fails to grab the object;(meaning the touch sensor is not touched)
the design of the robot is similar to the "Snatcher Robot" however we relocate the color sensor facing on the surface for the line following purposes while the touch sensor is placed in the former position of the color sensor; :(

Re: line follower (please help me)

Posted: 08 Dec 2011, 03:37
by mattallen37
A couple suggestions to help those who might be able to help you:
Use code tags like this

Code: Select all

[code]
[/code]
Come up with a flow-chart of if/else statements... so we know all the possible states, and what you want to happen.

Re: line follower (please help me)

Posted: 08 Dec 2011, 07:36
by mightor
Fixed the tags.

- Xander

Re: line follower (please help me)

Posted: 08 Dec 2011, 14:28
by hassenplug
dedeles wrote:i'm a student of a college here in Philippines. i'm having my thesis with some colleagues. we are having trouble controlling the robot using the line follower. we just copied some codes and we add some.
Wow. That's some pretty complex code. Looks like you did a bunch of copy/pasting to make that program.

Like Matt said, you really need to show us what you WANT the robot to do.

I can tell you a couple things about your program. This line is not a good idea:

Code: Select all

 while (ULSONIC == 32){
The value for the US sensor will jump around, so I think you want to know when ULSONIC is ~32 not exactly 32

Second, your value for 'error' is not correct. I'm going to guess your robot drives in circles.

It looks like you don't understand PID. If that's the case, you shouldn't use it.

Steve

Re: line follower (please help me)

Posted: 08 Dec 2011, 22:49
by dimasterooo
PID is hard, but there is a really great guide on learning it, applied to an NXT line follower, here: http://www.inpharmix.com/jps/PID_Contro ... obots.html. I'd go there, and maybe start from scratch because your program seems a bit over-complicated. I can also give you example code from a PID line follower I made if you want. It's in RobotC.

Re: line follower (please help me)

Posted: 11 Dec 2011, 03:51
by tabbycatrobots
First, I must echo the previous suggestions - prepare a document that describes what your project will do and how it
will do it. Second prepare a design spec for your hardware, e.g. motors, wheels, treads, sensors, what data the
various sensors will gather. Third, prepare a design spec for your software. This doesn't need be detailed to the
point of listing variables, but do list how many tasks, the functions, and what each function will accomplish, and whether
you will use global variables, or how you will pass data between functions. While creating these documents, I think
you may find errors in your design, and find these in 20 minutes of writing, rather than 3 hours of building or coding.
Also, I agree PID is difficult. Unless you need your robot to go very fast, following a complicated line, use simpler
code. The SmoothFollow program, a proportional line follower at <http://www.nxtprograms.com/NXT2/line_fo ... steps.html>
may be adequate. This is an NXT-G program, but is easily converted to NXC. See my recently uploaded zip file in the
projects forum, <Kemmel - Combining Line Following and Formula 1>, for my converted NXC code. I use a light sensor
for line following, and a color sensor for "seeing" color objects. I also use an ultrasonic for detecting objects; you may be
able to adapt this code to use with a touch sensor.
From your brief description, your project sounds interesting. When you get it working, please post a video.

Re: line follower (please help me)

Posted: 29 Dec 2011, 04:00
by dedeles
can you give me a complete code of a line follower??? :?:

Re: line follower (please help me)

Posted: 29 Dec 2011, 06:47
by dedeles
to dimasterooo,
sir, it would be a great help to us if you will send us a sample code of a PID controller... Maraming Salamat po, Ingat...

Re: line follower (please help me)

Posted: 13 Jan 2012, 07:32
by dedeles
can somebody explain what is "CurrentTick()" all about???... can't totally understand it.. thank you... :?

Re: line follower (please help me)

Posted: 13 Jan 2012, 14:24
by pepijndevos
*removed initial knee-jerk reaction* I was a little offended by your language and begging altitude. Sorry.

CurrentTick is a timer that is incremented 100 times a second, so it can be used for waiting and timing actions.