NXC - motors synchronization
NXC - motors synchronization
I need to turn motor OUT_A and OUT_B parallelly. Every motor has previously defined degree (signed) what i want to turn. The move must start and end in the same moment for these motors. How can i do it?
I thought about function RotateMotorEx (), but i dont understand how to use it like i wanted.
i have two variables which are needed to do it.
int x; // degree for OUT_A
int y; // degree for OUT_B
sorry about my english, i have problems with vocabulary conected with robots
I thought about function RotateMotorEx (), but i dont understand how to use it like i wanted.
i have two variables which are needed to do it.
int x; // degree for OUT_A
int y; // degree for OUT_B
sorry about my english, i have problems with vocabulary conected with robots
Re: NXC - motors synchronization
that's not precisely possible by NXC for any combination of target values: The synch mode is rather odd.
You only can roughly do this if you choose PWM-power in relation to the number of degrees to go.
You may choose independend PWM values for 2 independend motor control functions (1 specific call for each single motor).
So because you don't need a sync mode for just 1 motor, you may better use
instead of RotateMotorEx .
E.g. if A has to run 3000 degrees and B has to run 4000 degrees then you could choose pwrA=60 and pwrB=80
Start both in independend RotateMotor calls:
HTH!
You only can roughly do this if you choose PWM-power in relation to the number of degrees to go.
You may choose independend PWM values for 2 independend motor control functions (1 specific call for each single motor).
So because you don't need a sync mode for just 1 motor, you may better use
Code: Select all
void RotateMotor ( byte outputs, char pwr, long angle )
instead of RotateMotorEx .
E.g. if A has to run 3000 degrees and B has to run 4000 degrees then you could choose pwrA=60 and pwrB=80
Start both in independend RotateMotor calls:
Code: Select all
RotateMotor(OUT_A, 60, 3000);
RotateMotor(OUT_B, 80, 4000);
Re: NXC - motors synchronization
I am at 90% sure that RotateMotor function waits until rotation is done. It can be a problem -.-
Maybye 2 tasks with RotateMotor running paralelly?
Maybye 2 tasks with RotateMotor running paralelly?
Re: NXC - motors synchronization
yes, of course, if required!
-
- Posts: 1818
- Joined: 02 Oct 2010, 02:19
- Location: Michigan USA
- Contact:
Re: NXC - motors synchronization
If I needed precise control of keeping two motors closely in sync, I would try using a custom P or PD controller for the differential (and add and subtract that value to and from the two motor speeds).
Matt
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
Re: NXC - motors synchronization
precision is needed, because it will be a ploter.
How works RotateMotor? Does it wait until rotating is ended?
How to write this parallelly turning with tasks? Please, write an example for me
why it doesn't work (dsnt compile)
How works RotateMotor? Does it wait until rotating is ended?
How to write this parallelly turning with tasks? Please, write an example for me
Code: Select all
int Mox, Moy, a;
mutex Mx, My;
task MoveX()
{
Acquire (Mx);
RotateMotor (OUT_B, (50*Mox)/a, abs(Mox));
Release (Mx);
}
task MoveY()
{
Acquire (My);
RotateMotor (OUT_A, (50*Moy)/a, abs(Moy));
Release (My);
}
void PenMove (int x, int y)
{
PenPosx+=x;
PenPosy+=y;
x*=Cx;
y*=Cy;
a=max(x, -x);
int b=max(y, -y);
a=max(a, b);
Precedes (MoveX, MoveY);
Wait (100);
Acquire (Mx);
Release (Mx);
Acquire (My);
Release (My);
}
-
- Posts: 1818
- Joined: 02 Oct 2010, 02:19
- Location: Michigan USA
- Contact:
Re: NXC - motors synchronization
You need a main task, so the program knows where to start.psorek wrote:why it doesn't work (dsnt compile)
Matt
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
http://mattallen37.wordpress.com/
I'm all for gun control... that's why I use both hands when shooting
Re: NXC - motors synchronization
Do you have any thoughts as to why the code you posted might not compile? What do the error messages and their line numbers tell you?
One thing for sure is every NXC program requires a task called "main" which you don't have in what you posted. That's one problem. There are many others from what I can see.
Here's an example of how to start two tasks that each rotate a single motor:
The above code is completely untested and may not even compile.
John Hansen
One thing for sure is every NXC program requires a task called "main" which you don't have in what you posted. That's one problem. There are many others from what I can see.
Here's an example of how to start two tasks that each rotate a single motor:
Code: Select all
int power_a;
int angle_a;
int power_b;
int angle_b;
task moveA()
{
RotateMotor(OUT_A, power_a, angle_a);
}
task moveB()
{
RotateMotor(OUT_B, power_b, angle_b);
}
task waitForAB()
{
Follows(moveA, moveB);
// do something once both have reached their destination
PlayTone(TONE_A4, SEC_5);
ExitTo(startMovingAB);
}
task startMovingAB()
{
Precedes(moveA, moveB);
// calculate the correct values for power_a, power_b, angle_a, and angle_b
power_a = 40+Random(50);
power_b = 40+Random(50);
angle_a = 180+Random(3600)*sign(Random());
angle_b = 180+Random(3600)*sign(Random());
}
task main()
{
Precedes(startMovingAB);
}
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Re: NXC - motors synchronization
It was only part of code. I have to read about "Follows" function. I think so i know why it didn't work.
Re: NXC - motors synchronization
I have tried out the code I posted and with a couple minor changes it works great. You might consider using something like this approach for your plotter.
This program will randomly move A and B simultaneously at random power levels. Once both motors have reached their target the waitForAB task will start running and at the end of that task it starts up the startMovingAB task again which will choose new power levels and angle targets for OUT_A and OUT_B before scheduling the two motor movement tasks to run simultaneously again.
The RotateMotor API function calls Acquire and Release internally so there is no reason to explicitly acquire a mutex outside these function calls. Precedes and Follows are task scheduling directives rather than API commands, per se. They tell the compiler to configure the RXE executable so that the firmware's task scheduler will correctly schedule tasks to execute. The directives can be placed anywhere within a task or subroutine but they do not execute any code at runtime so their position within a routine is arbitrary. I recommend putting them at the start of the routine. If you tell the compiler that a task follows multiple other tasks then it will not execute until all of the tasks it follows have finished executing. This is a data-flow programming paradigm. All the required inputs to a routine must be available before the routine will begin to execute. The ExitTo routine allows you to at runtime tell the task scheduler to exit the current routine and schedule the specified routine to begin execution.
John Hansen
Code: Select all
int power_a;
int angle_a;
int power_b;
int angle_b;
task moveA()
{
RotateMotor(OUT_A, power_a, angle_a);
}
task moveB()
{
RotateMotor(OUT_B, power_b, angle_b);
}
task startMovingAB()
{
Precedes(moveA, moveB);
// calculate the correct values for power_a, power_b, angle_a, and angle_b
power_a = 40+Random(50);
power_b = 40+Random(50);
angle_a = 180+Random(3600)*sign(Random());
angle_b = 180+Random(3600)*sign(Random());
}
task waitForAB()
{
Follows(moveA, moveB);
// do something once both have reached their destination
PlayTone(TONE_A4, MS_500);
Wait(SEC_1);
ExitTo(startMovingAB);
}
task main()
{
Precedes(startMovingAB);
}
The RotateMotor API function calls Acquire and Release internally so there is no reason to explicitly acquire a mutex outside these function calls. Precedes and Follows are task scheduling directives rather than API commands, per se. They tell the compiler to configure the RXE executable so that the firmware's task scheduler will correctly schedule tasks to execute. The directives can be placed anywhere within a task or subroutine but they do not execute any code at runtime so their position within a routine is arbitrary. I recommend putting them at the start of the routine. If you tell the compiler that a task follows multiple other tasks then it will not execute until all of the tasks it follows have finished executing. This is a data-flow programming paradigm. All the required inputs to a routine must be available before the routine will begin to execute. The ExitTo routine allows you to at runtime tell the task scheduler to exit the current routine and schedule the specified routine to begin execution.
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Who is online
Users browsing this forum: No registered users and 4 guests