Hello,
I'm currently working on a robot simulator. The robot, let's say the "Plant", can be controlled by a speed controller or by a position controller. Like it's done in the rtt-exercices, I would like to switch the controller at runtine. Currently, I have one periodic activity for each component (Plant, SpeedController and PositionController). They both run at the same frequence, and the Plant input/output are permanently connected to both controller.
When I start the application, I do the following :
SpeedController.start()
Plant.start()
since I want the SpeedController to be executed before the Plant. When it's time to switch to PositionController, I run a script that does the following commands :
SpeedController.stop()
PositionController.start()
However, since the Plant has never been started, I guess the execution order would become : Plant first, PositionController second. I could have stopped the Plant before starting the PositionController. However, in the case of a "real" plant, I may not have the possibility to stop the plant task.
The only option that I see is using the SlaveActivity. I could have a main component which explicitly execute the slave activities. Since I'm using the deployer, the components don't really know each other so this option is almost impossible. What I would like to do is to fix the order of execution when deploying the component. In other words, the order of execution would be independent of start/stop sequences. Is there a way to do that?
Thank you,
Philippe Hamelin
Use case for switching controller
Submitted by phamelin on Thu, 2008-12-11 14:30 |
Use case for switching controller
On Thu, 11 Dec 2008, Philippe Hamelin wrote:
> I'm currently working on a robot simulator. The robot, let's say the
> "Plant", can be controlled by a speed controller or by a position
> controller. Like it's done in the rtt-exercices, I would like to switch the
> controller at runtine. Currently, I have one periodic activity for each
> component (Plant, SpeedController and PositionController). They both run at
> the same frequence, and the Plant input/output are permanently connected to
> both controller.
>
> When I start the application, I do the following :
>
> SpeedController.start()
> Plant.start()
>
> since I want the SpeedController to be executed before the Plant. When it's
> time to switch to PositionController, I run a script that does the following
> commands :
>
> SpeedController.stop()
> PositionController.start()
Oops... I don't like this approach _at all_!!! Using different activities
(threads) for different controllers is a very unfortunate thing to do, and
opens up more than one single can of worms :-)
Instead, you should use a _state machine_ (within one single activity) that
can switch between the _algorithms_ that implement your Plant,
SpeedController and PositionController.
Avoiding this "thread fiddling" development is _exactly_ the reason why I
started the Orocos projects 8 years ago ... :-)
> However, since the Plant has never been started, I guess the execution order
> would become : Plant first, PositionController second. I could have stopped
> the Plant before starting the PositionController. However, in the case of a
> "real" plant, I may not have the possibility to stop the plant task.
This kind of "scheduling" of threads to "guarantee" some causal path of
execution is not a good idea! If you need sequence garantees, please
program them explicitly in your state machine, and don't rely on any kind
of "application agnostic" scheduler.
Herman
> The only option that I see is using the SlaveActivity. I could have a main
> component which explicitly execute the slave activities. Since I'm using the
> deployer, the components don't really know each other so this option is
> almost impossible. What I would like to do is to fix the order of execution
> when deploying the component. In other words, the order of execution would
> be independent of start/stop sequences. Is there a way to do that?
>
> Thank you,
>
> Philippe Hamelin
>
>
>
--
Tel: +32 16 322480
K.U.Leuven, Mechanical Eng., Mechatronics & Robotics Research Group
Coordinator of EURON (European Robotics Research Network)
Open Realtime Control Services
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm
Use case for switching controller
On Dec 12, 2008, at 07:43 , Herman Bruyninckx wrote:
> On Thu, 11 Dec 2008, Philippe Hamelin wrote:
>
>> I'm currently working on a robot simulator. The robot, let's say the
>> "Plant", can be controlled by a speed controller or by a position
>> controller. Like it's done in the rtt-exercices, I would like to
>> switch the
>> controller at runtine. Currently, I have one periodic activity for
>> each
>> component (Plant, SpeedController and PositionController). They
>> both run at
>> the same frequence, and the Plant input/output are permanently
>> connected to
>> both controller.
>> When I start the application, I do the following :
>> SpeedController.start()
>> Plant.start()
>> since I want the SpeedController to be executed before the Plant.
>> When it's
>> time to switch to PositionController, I run a script that does the
>> following
>> commands :
>> SpeedController.stop()
>> PositionController.start()
>
> Oops... I don't like this approach _at all_!!! Using different
> activities
> (threads) for different controllers is a very unfortunate thing to
> do, and
> opens up more than one single can of worms :-)
> Instead, you should use a _state machine_ (within one single
> activity) that
> can switch between the _algorithms_ that implement your Plant,
> SpeedController and PositionController.
Bar trivial examples, I would strongly agree with Herman here. We use
a state-machine within our Plant to control whether it is safe,
holding position, or moving. We then have multiple controller
components, all of which are controlled by a master controller
component who is basically nothing more than a state machine dictating
which controller components are on/off. Then an HMI component sends
events to the two state machines (plant, and master controller) to
make the system do what it is supposed to.
Buried within the RTT and OCL code are examples like this, but it took
quite a jump for us to make a working system from them. One of my
thoughts is to actually extend Peter's examples/tutorials to include a
complete example like this, rather than have to burrow through
partially-working code to learn this.
HTH
S
Use case for switching controller
2008/12/12 S Roderick <kiwi.net@mac.com>
Ok, I will try to write out the use case to clarify some points to me.
Let's say we have a single Plant component, multiple Controller
components and a MasterController component. The Plant component and
the MasterController components have there own PeriodicActivity, while
each Controller components have a SlaveActivity.
A state machine is running inside the MasterController, which manages the execution of the Controller components. In other words, the state machine decides which SlaveActivity to execute at each step. By using a state machine, it's also possible to manage "transition" between control strategies.
However, tell me if i'm wrong, but I could also use a script instead of a state machine. It could be something like :
while(1)
{
try SpeedController.execute();
try PositionController.execute();
}
In addition to this script, I may need an other script to start/stop the Controllers. Like Peter said, if the controller is not started, the SlaveActivity will not be executed. However, with this script I can't manage the transitions between control strategies. I agree that a state machine if very versatile, but for a first design iteration it may work, am I wrong?
Thank you for your help!
Philippe Hamelin
Use case for switching controller
Use case for switching controller
On Thursday 11 December 2008 15:25:27 Philippe Hamelin wrote:
> Hello,
>
> I'm currently working on a robot simulator. The robot, let's say the
> "Plant", can be controlled by a speed controller or by a position
> controller. Like it's done in the rtt-exercices, I would like to switch the
> controller at runtine. Currently, I have one periodic activity for each
> component (Plant, SpeedController and PositionController). They both run at
> the same frequence, and the Plant input/output are permanently connected to
> both controller.
>
> When I start the application, I do the following :
>
> SpeedController.start()
> Plant.start()
>
> since I want the SpeedController to be executed before the Plant. When it's
> time to switch to PositionController, I run a script that does the
> following commands :
>
> SpeedController.stop()
> PositionController.start()
>
> However, since the Plant has never been started, I guess the execution
> order would become : Plant first, PositionController second. I could have
Correct.
> stopped the Plant before starting the PositionController. However, in the
> case of a "real" plant, I may not have the possibility to stop the plant
> task.
If you depend on ordering, SlaveActivity is the best choice.
>
> The only option that I see is using the SlaveActivity. I could have a main
> component which explicitly execute the slave activities. Since I'm using
> the deployer, the components don't really know each other so this option is
> almost impossible.
It isn't. You just need to appoint one component as master (which gets a
normal periodic activity), and make the other components peers of that
component (this is all done in XML, big note below (*!) ). The final thing you
need to do is
1. C++ : lookup the peers with
getPeer("the_slave")->engine()->getActivity()-execute()
(You'll be allowed to drop the engine() in RTT 1.8)
OR
2. Scripting:
try the_slave.execute(); // use 'do' or 'try'
So a dumb master could 'try' to execute all its slaves in the desired order.
Only the ones started will actually execute.
> What I would like to do is to fix the order of execution
So do this in a program script or in C++.
Peter
(*!) Due to a 'bug', you're unable to specify a master using XML in the OCL
1.6 library. This has as effect that you need to specify the period manually in
the XML file and can not 'inherit' it from a master task. Also, you're then
allowed to start the slave even if the master is not running. This will be
fixed in OCL 1.8.