NXC: motor rotate to a specific ("absolute") encoder target

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: motor rotating to a encoder target

Post by HaWe »

next problem (important when the "mounted-other-way-round-problem" has been resolved):
How can one know if the motor is still busy (moving) while the encoder target has not been reached yet
- or -
if the motor is in "stop mode" or in "hold position mode" or in "position correction mode" if it has just reached the target ?
schodet
Posts: 139
Joined: 29 Sep 2010, 11:21
Contact:

Re: NXC: motor rotating to a encoder target

Post by schodet »

doc-helmut wrote:

Code: Select all

safecall void RotateToEncoderTarget(char port, char pwr, int accel, long target) {
  SetMotorRegulationTime (10);
  PosRegEnable (port);                 
  PosRegSetMax (port, pwr, accel);           
  PosRegSetAngle (port, target);
}
to my observation it does not work with motors working "the other way round" (because mounted other way round or because of an intermediate gear).
You are not supposed to use PosRegEnable each time you change the angle because it will reset counters to the current position. If that does not solve the problem please post a minimal code which reproduce your problem.

Nicolas.
LEGO things http://ni.fr.eu.org/lego/ - NXT Improved Firmware (GCC) http://nxt-firmware.ni.fr.eu.org/ - Other robots http://apbteam.org
schodet
Posts: 139
Joined: 29 Sep 2010, 11:21
Contact:

Re: NXC: motor rotating to a encoder target

Post by schodet »

doc-helmut wrote:How can one know if the motor is still busy (moving) while the encoder target has not been reached yet
- or -
if the motor is in "stop mode" or in "hold position mode" or in "position correction mode" if it has just reached the target ?
There is no mode with absolute regulation, the firmware is always controlling the motor to the requested position.

Until now, the only way you can use to know if the move is finished is to monitor the current position. OK, that's to be improved.
LEGO things http://ni.fr.eu.org/lego/ - NXT Improved Firmware (GCC) http://nxt-firmware.ni.fr.eu.org/ - Other robots http://apbteam.org
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: motor rotating to a encoder target

Post by HaWe »

Nicolas,
If I intermediately had set all motors to coast:
Don't I have to initialize PosRegEnable (port) everytime before starting PosRegSetAngle again?

But I meanwhile think maybe the PosReg functions are not suitable for my purposes.
They are used for a 5(-6) DOF industry robot which has to move to several dozens (>60) of different destination targets (in 3D space).

What I want to do is: move to 3D_target_1 as close as possible,
when it finally has been reached: switch to coast (motors have to be unblocked!);
then do something different (e.g. position fine tuning by light and distance sensors, grabbing);
then approach a new 3D_target_2 as close as possible,
when it finally has been reached: switch to coast (motors again have to be unblocked!);
then do something different (e.g. position fine tuning by light and distance sensors, grabbing);
and so on.

Simultaneously 3 motors have to be moved.

This is the program flow plan in pseudo code:

Code: Select all

// aproach 1st target
while (!AllTargetsReached) {
  RotateToTarget(OUT_A,...-6000);  
  RotateToTarget(OUT_B,...+1000);  
  RotateToTarget(OUT_C,...+ 200);
} // do until all targets are reached
Coast(OUT_A); Coast(OUT_B); Coast(OUT_C);    // as soon as all targets have been reached: switch to coast;
... // do sth specific
...
// aproach 2nd target
while (!AllTargetsReached) {
  RotateToTarget(OUT_A,...-4000);  
  RotateToTarget(OUT_B,...+2000);  
  RotateToTarget(OUT_C,...+ 500);
} // do until all targets are reached
Coast(OUT_A); Coast(OUT_B); Coast(OUT_C);    // as soon as all targets have been reached: switch to coast;
... // do sth specific
...
// aproach 3rd target
while (!AllTargetsReached) {
  RotateToTarget(OUT_A,...-5000);  
  RotateToTarget(OUT_B,...+3000);  
  RotateToTarget(OUT_C,...-1000);
} // do until all targets are reached
Coast(OUT_A); Coast(OUT_B); Coast(OUT_C);    // as soon as all targets have been reached: switch to coast;
... // do sth specific
...
// a.s.o.
ps
As all rotations of all ports have to be done simultaneously, I meanwhile use my own MoveToTarget functions for each single port (a simple PD), each working in a private task and setting semaphores if the related targets are reached
schodet
Posts: 139
Joined: 29 Sep 2010, 11:21
Contact:

Re: NXC: motor rotating to a encoder target

Post by schodet »

Well, in this case, you may need to have a modified code for PosRegEnable. Current code is:

Code: Select all

inline void PosRegEnable(byte output, byte p = PID_3, byte i = PID_1, byte d = PID_1)
{
    SetOutput(output,
               OutputModeField, OUT_MODE_MOTORON+OUT_MODE_BRAKE+OUT_MODE_REGULATED,
               RegModeField, OUT_REGMODE_POS,
               RunStateField, OUT_RUNSTATE_RUNNING,
               PowerField, 0,
               TurnRatioField, 0,
               RegPValueField, p, RegIValueField, i, RegDValueField, d,
               UpdateFlagsField, UF_UPDATE_MODE+UF_UPDATE_SPEED+UF_UPDATE_PID_VALUES+UF_UPDATE_RESET_COUNT);
    Wait(MS_2);
}
Try to remove the UF_UPDATE_RESET_COUNT flag with a simple program :

- go to 180,
- wait,
- float,
- wait
- go to 0,
- wait,

The motor should return to its start position.
LEGO things http://ni.fr.eu.org/lego/ - NXT Improved Firmware (GCC) http://nxt-firmware.ni.fr.eu.org/ - Other robots http://apbteam.org
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: motor rotating to a encoder target

Post by HaWe »

thx for contributing!
what I don't understand yet:
PosRegEnable currently has only 1 parameter (port),
but in you example it has 4! (byte output, byte p = PID_3, byte i = PID_1, byte d = PID_1)
if I'll write a new private function without reset_counter, how should I use it?
(we don't have function overloading, do we?)
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: NXC: motor rotating to a encoder target

Post by mattallen37 »

doc-helmut wrote:...what I don't understand yet:
PosRegEnable currently has only 1 parameter (port),
but in you example it has 4! (byte output, byte p = PID_3, byte i = PID_1, byte d = PID_1)...
That's because the other parameters default to certain values, so they are optional when you use the function in your program.

It's like most of the NXC drawing functions. You set (for example) X, Y, Radius, and optionally draw options. You aren't required to use the last parameter, but if you don't, it will default to some value (in this case to DRAW_OPT_NORMAL).
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: motor rotating to a encoder target

Post by HaWe »

thx!
so my function now should read like this...? (the syntax is a little uncommon to me, passing both a variable name as well as it's value)

Code: Select all

inline void myPosRegEnable(byte output)
{
    SetOutput(output,
               OutputModeField, OUT_MODE_MOTORON+OUT_MODE_BRAKE+OUT_MODE_REGULATED,
               RegModeField, OUT_REGMODE_POS,
               RunStateField, OUT_RUNSTATE_RUNNING,
               PowerField, 0,
               TurnRatioField, 0,
               RegPValueField, p, RegIValueField, i, RegDValueField, d,
               UpdateFlagsField, UF_UPDATE_MODE+UF_UPDATE_SPEED+UF_UPDATE_PID_VALUES);
    Wait(MS_2);
}
schodet
Posts: 139
Joined: 29 Sep 2010, 11:21
Contact:

Re: NXC: motor rotating to a encoder target

Post by schodet »

doc-helmut wrote:thx!
so my function now should read like this...? (the syntax is a little uncommon to me, passing both a variable name as well as it's value)
You must keep the p, i and d parameters, or they will be unknown by the compiler. This is the same syntax as C++, to give parameters a default value.
LEGO things http://ni.fr.eu.org/lego/ - NXT Improved Firmware (GCC) http://nxt-firmware.ni.fr.eu.org/ - Other robots http://apbteam.org
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: motor rotating to a encoder target

Post by HaWe »

will this redefined function then automatically overwrite the genuine version of the API?
and I'm not quite sure how to write a task which lets a motor approach a target and then automatically stops when finally has reached a certain preciseness (e.g., 5 degrees) - and then signalizes this achievement by a flag.

It's actually an issue at certain squares for my chess robot, especially for far-off squares or even those very close to the turn table.
I need much torque till the end as well as exact positioning of ~5 degrees (I now get about 20-25 degrees at 80-100% PWM corresponding to about 5-6 mm by the screw drive).
All motors have to run simultaneously, each one to his own special target.
Sometimes a single motor has to stop intermediately and needs to be synchronized and to wait until another motor has reached his intermediate target, and then start anew to reach another intermediate or even the final target (some work space areas obstruct and limitate themselves and each other in certain combinations). So a task has to stay intermediately in cetain hold-and-wait-states until it finally stops exactly where it should without oscillation.
Post Reply

Who is online

Users browsing this forum: No registered users and 42 guests