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

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

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

Post by afanofosc »

manifold function calls are extremely complicated to handle
Doc, could you help me better understand what you mean by this phrase? Do you mean SetOutput with its ability to take a variable number of arguments? If that bothers you then use SetOutput multiple times for each individual output module IOMap field. Like this:

Code: Select all

    SetOutput(output, OutputModeField, OUT_MODE_MOTORON+OUT_MODE_BRAKE+OUT_MODE_REGULATED);
    SetOutput(output, RegModeField, OUT_REGMODE_POS);
    SetOutput(output, RunStateField, OUT_RUNSTATE_RUNNING);
    SetOutput(output, PowerField, 0);
    SetOutput(output, TurnRatioField, 0);
    SetOutput(output, RegPValueField, p); 
    SetOutput(output, RegIValueField, i);
    SetOutput(output, RegDValueField, d);
    SetOutput(output, UpdateFlagsField, UF_UPDATE_MODE+UF_UPDATE_SPEED+UF_UPDATE_PID_VALUES);
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

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

Post by HaWe »

it actually don't bother me, it more confuses me looking at schodet's code and trying to fit it into my own program structure.
What I'm doing is also probably not what schodet's function is designed for, and surely the multiple args of SetOutput don't make it easier.
But you probably will think that my own functions which I'm using in my program are much more confusing than those you suggest to use
(maybe everyone thinks his own program is working much more logical than any other because he was the one who designed and constructed it, I mean: he got some head start in thinking for his own "invention").

If you want to see how my "RobotC-pseudo-code" which I suggested would work compared to e.g., schodet's it would look like this
(this is all what I would need compared to the 60 lines of schodet's code WHICH I DON'T WANT TO CRITIZISE IN NO RESPECT!) :

Code: Select all

SetMotorRotationTarget(OUT_A, -1000);  // define 3 target values
SetMotorRotationTarget(OUT_B, -2000);
SetMotorRotationTarget(OUT_C, 50);
RotateToTarget(OUT_A, 100); // start of all 3 motors simultaneously
RotateToTarget(OUT_B, 100);
RotateToTarget(OUT_C, 80);
while ( (MotorRunstate(OUT_A)!=IDLE) && (MotorRunstate(OUT_B)!=IDLE) && (MotorRunstate(OUT_C)!=IDLE)); // wait until all are finished
Coast(OUT_ABC);
(edited)

// for the next 3D target in case OUT_C then might not have to be changed I would write just :

Code: Select all

SetMotorRotationTarget(OUT_A, -2000); // define 2 target values
SetMotorRotationTarget(OUT_B, 1000);
RotateToTarget(OUT_A, 100); // start of 2 motors simultaneously, OUT_C keeps idle
RotateToTarget(OUT_B, 100);
while ( (MotorRunstate(OUT_A)!=IDLE) && (MotorRunstate(OUT_B)!=IDLE)); // wait until all are finished
Coast(OUT_ABC);
again, this is no critic of your's or schodet's code it should only demonstrate what my attempt is.
Last edited by HaWe on 02 Feb 2012, 07:59, edited 1 time in total.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

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

Post by afanofosc »

So, doc, what do you mean by the phrase I quoted? I am seeking only to understand.

Also, to understand, what do you want your motors to do when they reach their target? Shut off power and coast to a stop? Hold the motor with powered brake at the target? Do you want your motors to ramp up or down during their progress toward the new target? Give me a detailed specification and I can try to show you how to do what you want to do. I assume that part of this spec is that you want the firmware to ignore manual motor position changes before it begins rotating to the next target.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

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

Post by HaWe »

well, many questions...

1) what indeed confuses me is that I have to use RotateMotor which got too many args I have to write and handle (and admittedly don't understand)
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);

next is the use and functionality of PosRegEnable and PosRegSetMax I have to write and to consider.
then there is some intermediate OnFwdEx (OUT_ABC, 30, RESET_NONE) I have to use.
and another PosRegRestart(OUT_A); which apperas to be of any importance
and so on: too many words and too many lines for just a simple target to approach, that's what I meant by "manifold function calls are extremely complicated to handle"

2) provided that normally such a "goto-absolute-encoder-target-function" would "hold/stop" when reaching the target, then I would need to set it to "coast/float" for my special case.
Of course in other programs it might be more useful to keep the motors in "hold/stop" mode, I wouldn't have to use the coast command then.

3) Mainly the motors should approach their targets as close as possible in any way. Ramping is not required necessarily, but it might make it easier stopping right at the correct target value. There might be cases when a motor has a heavy load to move up, then it will have to have almost all the power (80-100) till the end; maybe there is a heavy load to move down, then the movement may run almost by itself, and the motor will have to get just little power (10-20) or even negative power to brake the movement.

4) Intermediately I need to have the functionality to adjust a position manually.
In my case - of course - it's for the chess robot. During a long chess game it may happen that I recognize that the coordinates of one square have been stored or coincidentally approached incorrectly. In that case I want to adjust the arm position manually.
(Maybe that event was only coincidentally , then nothing else will have to be done; but i e.g., when it was a systematic failure then I might press a certain button to store the 3 corrected current encoder values of this special square for future use and overwrite the wrong value of the lookup table (teach-in-mode); the corrected table will be stored to the flash and be reloaded with the corrected values at the next program start ).

well, did I answer all question or did I miss one?
Last edited by HaWe on 01 Feb 2012, 18:32, edited 1 time in total.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

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

Post by afanofosc »

To further understand, you want the value that you set as the target to be absolute as opposed to relative to the current position, i.e,. -2000 would result in rotating counter clockwise 5000 degrees if the current motor position is 3000.

I'm also not sure how you want the NXT to ignore some motor movements but not others (i.e., the manual ones). You may need to somehow tell your program that you are switching into an adjustment phase which it should ignore, and then switching out of the adjustment phase so that it should stop ignoring motor rotations. Any resetting of a tachometer counter, either by the firmware for its own reasons or by your program will make it extraordinarily hard to maintain something "absolute" since you have just changed the 0 point of your axis.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

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

Post by HaWe »

To further understand, you want the value that you set as the target to be absolute as opposed to relative to the current position, i.e,. -2000 would result in rotating counter clockwise 5000 degrees if the current motor position is 3000.
yes, that's correct.

Code: Select all

SetMotorRotationTarget(OUT_A, -1000);  // define absolute  target value
RotateToTarget(OUT_A, 100); // start rotation task; self-terminating when the absolute target has been reached 
You may need to somehow tell your program that you are switching into an adjustment phase which it should ignore, and then switching out of the adjustment phase so that it should stop ignoring motor rotations.
The RotateToTarget task (or: function processed inside a task) has to run autonomously self-controlled until the target has been reached; during that time the MotorRunstate is "BUSY". Manual corrections are not intended in this phase, but if they happen accidentally, then the motor control task should re-correct them.
Intermediate premature termination by other tasks must be possible (regardless of any mutexes).

If once the absolute target has been reached, the control task is self-terminating and switches off the motor (MotorRunstate switched to "IDLE"), now this is finished. You can see if the task is finished by

Code: Select all

if (MotorRunstate(OUT_A)==IDLE) {...} // if it's true then the absolute target has been reached and the task is finished!
I now might do anything or nothing, e.g. now make some intermediate corrections. During manual correction the manual rotation of course is monitored by a change of the MotorRotationCount value. The program knows what the current position is anyway (either if changed or not) and will have to approach the next target regardless if any adjustment has been made or not, e.g.:
If the current position is 1000 and the next target will be 1500 then the next function call will move 500 clockwise.
If the current position is 1000, and I should move it manually to 900, and also the next target will be 1500, then the next function call will have to move 600 clockwise.

The zero point which is initialized at program start (ResetRotationCount) will not be affected
- unless I will make an additional re-initialization intermediately (e.g. if someone severely hit or twisted an arm or the turn table accidentally).
schodet
Posts: 139
Joined: 29 Sep 2010, 11:21
Contact:

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

Post by schodet »

Doc, I really have a hard time to understand what you are missing. The program I posted just do that. The OnFwdEx is an example of a "small adjustment" and the firmware still always maintain the motor position.

The PosRegRestart is a function you can copy without modification to enable absolute regulation without reseting position. PosRegSetAngle is the equivalent of SetMotorRotationTarget.

For me, you have everything you need to make it work.
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 rotate to a specific ("absolute") encoder target

Post by HaWe »

well you may be right from your point of view but for me it's too complicated to handle.
Sth like RobotC got would be much easier:

Code: Select all

SetMotorRotationTarget(OUT_A, -1000);  // define absolute  target value
RotateToTarget(OUT_A, 100); // start rotation task; self-terminating when the absolute target has been reached 
(nothing else required - Xander may CMIIW: and this is absolutely no RobotC bashing^^)
or, all-in-one -

Code: Select all

RotateToAbsoluteTarget(OUT_A, -1000, 100); // (port, target, pwr).
I really can't handle your code in my program tasks, your absolute regulation is simply not designed for my purposes.

I will try more with mattallen's code, http://sourceforge.net/apps/phpbb/mindb ... 279#p11766 it's actually what I would need, only the P-I-D-adjustment is not already optimized yet.
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests