Need help combining steering with odometry in NXC

View: New views
4 Messages — Rating Filter:   Alert me  

Need help combining steering with odometry in NXC

by Joe Strout-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm working on an NXT bot to do the Trinity College Fire Fighting Robot Contest
(http://www.trincoll.edu/events/robot/), at least well enough to get through
this Saturday's demo at the local science museum.  At the moment, I'm just
trying to get the robot to follow the wall (which is white on a black floor, so
think of it as line-following), while also having odometry to tell how far I've
gone.

But so far, nothing I've tried seems to work.  I thought I could just do

  OnFwdSync( OUT_AC, 75, 0 );

before my wall-following loop, and then within the loop, based on the sensor
input, call

  SetOutput( OUT_AC, TurnRatio, turnRatio );

(where I'm confident that "turnRatio" is properly calculated).  But this doesn't
seem to make the robot turn at all.  So instead, I've had to call OnFwdSync with
my continually-updated turnRatio inside the loop.  That makes it turn fine, but
it also seems to continually reset the tachometer counts.  This is true even
when I instead use

  OnFwdSyncEx( OUT_AC, 75, turnRatio, RESET_NONE );

which I thought explicitly told it not to reset the tacho counts.

This seems like such a simple task, surely I'm not the first to attempt it.
What's the recommended procedure for steering (adjusting the turn ratio) inside
a sensor loop, without losing your tachometer counts?

Many thanks,
- Joe

Re: Need help combining steering with odometry in NXC

by Joe Strout-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

In lugnet.robotics, Joe Strout wrote:

> This is true even when I instead use
>
>   OnFwdSyncEx( OUT_AC, 75, turnRatio, RESET_NONE );
>
> which I thought explicitly told it not to reset the tacho counts.

Update: upon a couple more hours' testing, I found that the above command
actually prevents the bot from turning at all.  It will only turn if I pass at
least RESET_BLOCK_COUNT for the last parameter (of course other combinations
that include resetting the block count, e.g. RESET_ALL, also work).

Whew, that was a couple of hours wasted!  Lesson learned, but I still don't seem
to be getting good tacho counts, and I'm still curious whether there is a
standard NXC loop for following a line while measuring distance travelled.

Thanks,
- Joe

Re: Need help combining steering with odometry in NXC

by John Hansen-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

In lugnet.robotics, Joe Strout wrote:
> I'm working on an NXT bot to do the Trinity College Fire Fighting Robot Contest
> (http://www.trincoll.edu/events/robot/), at least well enough to get through
> this Saturday's demo at the local science museum.  At the moment, I'm just
> trying to get the robot to follow the wall (which is white on a black floor, so
> think of it as line-following), while also having odometry to tell how far I've
> gone.
>

If you are really following a line then you should use a traditional line
following algorithm rather than try to use motor synchronization and turn
ratios.  There isn't any reason to synchronize the motors since following a line
usually involves lots of slight course corrections that are controlled by light
sensor readings.  

The motor tachometer is the RotationCount field.  Both the TachoCount and
BlockTachoCount are for primarily internal use by the firmware's PID control
algorithm and may be reset outside of your control.  The RotationCount field is
only reset when you explicitly tell it to be reset via ResetRotationCount,
ResetAllTachoCounts, or by passing RESET_ALL (0x68) or RESET_ROTATION_COUNT
(0x40) into one of the Ex motor control functions.  To read the RotationCount
field just use MotorRotationCount(port) or GetOutput(port, RotationCount).

John Hansen

Re: Need help combining steering with odometry in NXC

by John Hansen-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

In lugnet.robotics, Joe Strout wrote:

> In lugnet.robotics, Joe Strout wrote:
>
>> This is true even when I instead use
>>
>>   OnFwdSyncEx( OUT_AC, 75, turnRatio, RESET_NONE );
>>
>> which I thought explicitly told it not to reset the tacho counts.
>
> Update: upon a couple more hours' testing, I found that the above command
> actually prevents the bot from turning at all.  It will only turn if I pass at
> least RESET_BLOCK_COUNT for the last parameter (of course other combinations
> that include resetting the block count, e.g. RESET_ALL, also work).
>
> Whew, that was a couple of hours wasted!  Lesson learned, but I still don't seem
> to be getting good tacho counts, and I'm still curious whether there is a
> standard NXC loop for following a line while measuring distance travelled.
>

Here is a line follower from my book, NXT Power Programming:

#define SLOW_SPEED 25
#define FAST_SPEED 75
#define EYE_PORT   S1
#define EYE_VALUE  SENSOR_1

int BlackThreshold;
int WhiteThreshold;

inline int min(int v1, int v2) {
  return (v1 < v2) ? v1 : v2;
}

inline int max(int v1, int v2) {
  return (v1 > v2) ? v1 : v2;
}

task main() {
  // set sensor type and mode
  SetSensorType(EYE_PORT, SENSOR_TYPE_LIGHT_ACTIVE);
  SetSensorMode(EYE_PORT, SENSOR_MODE_RAW);
  ResetSensor(EYE_PORT);

  int lowest, highest, SV;
  lowest  = 10000;
  highest = -10000;
  while (!ButtonPressed(BTNLEFT, false)) {
    SV = EYE_VALUE;
    lowest  = min(lowest, SV);
    highest = max(highest, SV);
    NumOut(0, LCD_LINE1, SV);
  }
  BlackThreshold = lowest+200;
  WhiteThreshold = highest-200;
  NumOut(0, LCD_LINE1, BlackThreshold, true);
  NumOut(0, LCD_LINE2, WhiteThreshold);
  until(ButtonPressed(BTNCENTER, false));
  while (true) {
    SV = EYE_VALUE;
    if (SV < WhiteThreshold)
      OnFwd(OUT_A, FAST_SPEED);
    else
      OnFwd(OUT_A, SLOW_SPEED);
    if (SV > BlackThreshold)
      OnFwd(OUT_C, FAST_SPEED);
    else
      OnFwd(OUT_C, SLOW_SPEED);
  }
}


All you need to do to read OUT_A's rotation count is insert a call to
MotorRotationCount(OUT_A) within the while loop at the end.  You could reset the
rotation count just prior to the final while loop and break out of the loop when
the OUT_A rotation count exceeds your limit.

John Hansen
LightInTheBox - Buy quality products at wholesale price!