user1131951
user1131951

Reputation: 151

Difference between NXT-G visual programming and NXC C-like programming of Lego brick

I'm approaching to Lego NXT programming and I started from the very good site http://nxtprograms.com . In particular I followed instructions for the simple Segway with light sensor as balancing sensor (http://nxtprograms.com/NXT2/segway/index.html). I studied his (Dave Parker) NXT-G program and successfully replicated on his robot and on a simpler custom version (without the "driver"). Everything works, either his program and mine. I quite immediately switched to NXC programming because I already know the C lang and wanted to exploit the larger potentiality. I replicated the balancing algorithm quite well with the very same PID constants and calculations. The result is that the C program just doesn't work: the robot balances itself for 1 or 2 seconds, the oscillations are larger than those one with NXT-G and it falls down.

I compared the NXT-G and C base logics without finding any difference. So I wonder if something is wrong, in my program, with motor control. I suppose that the NXT-G graphical box controlling the motors does something more that simply invoke OnFwdSync(...)/OnRevSync(...). This would explain why my program produces large initial oscillations.

Does anybody have an example of NXC program driving that simple segway-lego or can explain why the motor control in my program fails ? In the bottom I've attached the source code of my program.

thanks.

#define KP 25
#define KI 1
#define KD 10
#define KO 0.5
#define LSAMPLE 100
//#include "MotorActions.nbc"

int balance(const int RIF)
{
  int output = 0;
  int previous_error = 0;
  int error = 0;
  int I = 0;
  int D = 0;
  int counter = 0;
  int actual;

  while (true)
  {
    actual = SENSOR_3;
    error = actual - RIF;
    counter++;
    I += error;
    D = (error - previous_error);
    previous_error = error;
    /**
     *  Compute de PID compensation
     */
    output = KO * (KP * error + KI * I + KD * D);
    if ((output > 1000) || (output < -1000)) 
      break;
    if (output < 0)
      OnFwdSync(OUT_BC, -output, 0);
    else
      OnRevSync(OUT_BC, output, 0);
  }
  return (counter);
}

int read_light()
{
  int L = 0;
  int ctr = 0;

  while (ctr < LSAMPLE)
  {
    L += SENSOR_3;
    ctr++;
    Wait(10);
  }
  return (L / LSAMPLE);
}

task main()
{
  int i = 0;
  int RIF;
  int count;

  while (i++ < 3)
  {
    //PlaySound(SOUND_LOW_BEEP);
    Wait(800);
  }
  Wait(400);
  //PlaySound( SOUND_DOUBLE_BEEP );
  SetSensorColorRed(IN_3);
  ClearSensor(SENSOR_3);
  RIF = SENSOR_3;
  count = balance(RIF);
  Off(OUT_BC);
}

Upvotes: 1

Views: 1633

Answers (1)

Joseph Dykstra
Joseph Dykstra

Reputation: 1466

Try changing your constants. Try raising KP to a larger value, 32, maybe?

Upvotes: 1

Related Questions