MotionCommand Class Reference#include <MotionCommand.h>
Inheritance diagram for MotionCommand:
[legend]List of all members.
Detailed Description
The abstract base class for motions, provides common interface. All motions should inherit from this.
For instructions on how to create:
- a new subclass of MotionCommand, read on. Also see the step-by-step guide
- an instantiation of a MotionCommand subclass, see MotionManager
To create a new type of motion, you'll want to subclass this. You don't need to do anything fancy, but just be sure to override the 3 abstract functions.
When an output is set to a value, that output is held at that value until it is set to a new value, even if the MotionCommand that set it is pruned or stops using the output. Outputs never "reset" to 0 or some other relatively arbitrary base value if all the MotionCommands are removed.
However, PID values will reset to the default values if pruned or not set since these values do have a base value which you will want to use 99% of the time.
Be aware that there is a delay between when you set a joint to a value and that actually is taken into account by the system - it's on the order of FrameTime*NumFrames (currently 8*4 = 32 ms, so worse case 2*8*4 = 64 ms) This is because the commands are double buffered. PIDs, on the other hand, seem to take effect more quickly. This un-synchronization can sometimes cause a bit of jerkiness (mainly on startup, where there's a large difference between desired and target values.)
Here is the cycle of calls made by MotionManager to your command:
- shouldPrune() (by default, this will return !isAlive() iff autoprune==true)
- updateJointCmds() (assuming the MC wasn't pruned after the previous step)
So, if you want to hold a joint at a value, each time your updateJointCmds() function is called, you should tell the MotionManager to keep the joint there (using one of MotionManager::setOutput()'s). If you do not set a joint after a call to updateJointCmds, the MotionManager will assume you are no longer using that joint and a lower priority MotionCommand may inherit it.
MotionCommands which generate events should use the inherited postEvent() instead of trying to access a global erouter - the inherited version will properly handle sending the events regardless of the current context, but trying to access a non-shared global like erouter could cause problems.
- Warning:
- Be careful what you call in MotionManager
Some functions are marked MotionCommand-safe - this is another issue due to our "fake" fork. In short, when a function is called on a MotionCommand, it uses the context of whatever process created it, not the process that actually made the function call. Thus, when Motion calls updateOutputs(), calls that the MotionCommand makes are indistinguishable from concurrent calls from Main. This can cause deadlock if a function is called which locks the MotionManager. To get around this, we need to pass the 'this' parameter on functions that require a lock, namely MotionManager::setOutputs(). This allows the MotionManager to figure out that it's the same MotionCommand it previously called updateOutputs() on, and thus avoid trying to lock itself again.
Don't store pointers in motion commands!
Since motion commands are in shared memory, and these shared memory regions can have different base pointers in each process, pointers will only be valid in the process from which they were assigned. In other processes, that address may point to something else, especially if it was pointing outside of the shared memory regions.
There are convoluted ways of getting around this. If needed, MotionManager could be modified to hand out shared memory regions upon request. Let's try to avoid this for now. Keep MotionCommands simple, without dynamic memory. Do more complicated stuff with behaviors, which only have to worry about running in Main.
Definition at line 87 of file MotionCommand.h.
|
*** INHERITED: *** |
| MotionCommand () |
| Constructor: Defaults to kStdPriority and autoprune==true.
|
virtual | ~MotionCommand () |
| Destructor.
|
virtual void | DoStart () |
| called after this is added to MotionManager
|
virtual void | DoStop () |
| called after this is removed from MotionManager
|
virtual bool | isActive () const |
| returns true if the MotionCommand is currently running (although it may be overridden by a higher priority MotionCommand)
|
virtual bool | getAutoPrune () |
virtual void | setAutoPrune (bool ap) |
virtual bool | shouldPrune () |
| whether this motion should be removed from its motion group automatically ( MotionCommand::autoprune && !isAlive())
|
void | setTranslator (EventTranslator *q) |
| only called from MMCombo during process setup, allows MotionCommands to send events
|
static double | interpolate (double a, double b, double x) |
| this utility function will probably be of use to a lot of MotionCommand's
|
static float | interpolate (float a, float b, float x) |
| this utility function will probably be of use to a lot of MotionCommand's
|
static void | interpolate (const OutputCmd &a, const OutputCmd &b, float x, OutputCmd &r) |
| this utility function will probably be of use to a lot of MotionCommand's, see interpolate(double a,double b,double r)
|
Public Member Functions |
|
virtual int | updateOutputs ()=0 |
| is called once per update cycle, can do any processing you need to change your priorities or set output commands on the MotionManager
|
virtual int | isDirty ()=0 |
| not used by MotionManager at the moment, but could be used to reduce recomputation, and you may find it useful
|
virtual int | isAlive ()=0 |
| used to prune "dead" motions from the MotionManager
|
Protected Member Functions |
void | postEvent (const EventBase &event) |
| calls EventTranslator::trapEvent() directly (avoids needing erouter, which is a non-shared global, causes problems with context, grr, silly OS)
|
Protected Attributes |
EventTranslator * | queue |
| send events using this, instead of posting to the erouter
|
int | autoprune |
| default true, autoprune setting, if this is true and isAlive() returns false, MotionManager will attempt to remove the MC automatically
|
bool | started |
| true if the MotionCommand is currently running (although it may be overridden by a higher priority MotionCommand)
|
Private Member Functions |
| MotionCommand (const MotionCommand &) |
| don't call
|
MotionCommand & | operator= (const MotionCommand &) |
| don't call
|
Constructor & Destructor Documentation
MotionCommand::MotionCommand |
( |
|
) |
[inline] |
|
|
Constructor: Defaults to kStdPriority and autoprune==true.
Definition at line 119 of file MotionCommand.h. |
virtual MotionCommand::~MotionCommand |
( |
|
) |
[inline, virtual] |
|
Member Function Documentation
virtual void MotionCommand::DoStart |
( |
|
) |
[inline, virtual] |
|
|
called after this is added to MotionManager
Reimplemented in HeadPointerMC, LedMC, OldHeadPointerMC, PIDMC, PostureMC, RemoteControllerMC, and WalkMC.
Definition at line 124 of file MotionCommand.h.
Referenced by WalkMC::DoStart(), RemoteControllerMC::DoStart(), PostureMC::DoStart(), PIDMC::DoStart(), OldHeadPointerMC::DoStart(), LedMC::DoStart(), and HeadPointerMC::DoStart(). |
virtual void MotionCommand::DoStop |
( |
|
) |
[inline, virtual] |
|
virtual bool MotionCommand::getAutoPrune |
( |
|
) |
[inline, virtual] |
|
static void MotionCommand::interpolate |
( |
const OutputCmd & |
a, |
|
|
const OutputCmd & |
b, |
|
|
float |
x, |
|
|
OutputCmd & |
r |
|
) |
[inline, static, protected] |
|
|
this utility function will probably be of use to a lot of MotionCommand's, see interpolate(double a,double b,double r)
interpolates both value and weights of JointCmd's - Parameters:
-
| a | first joint cmd |
| b | second joint cmd |
| x | weight to favor b's value and weight |
| r | joint cmd to store the result |
Definition at line 172 of file MotionCommand.h. |
static float MotionCommand::interpolate |
( |
float |
a, |
|
|
float |
b, |
|
|
float |
x |
|
) |
[inline, static, protected] |
|
|
this utility function will probably be of use to a lot of MotionCommand's
Does a weighted average of a and b, favoring b by x percent (so x==0 results in a, x==1 results in b) - Parameters:
-
| a | first value |
| b | second value |
| x | weight of second value as opposed to first |
- Returns:
- Todo:
- replace with a more fancy spline based thing?
Definition at line 163 of file MotionCommand.h. |
static double MotionCommand::interpolate |
( |
double |
a, |
|
|
double |
b, |
|
|
double |
x |
|
) |
[inline, static, protected] |
|
|
this utility function will probably be of use to a lot of MotionCommand's
Does a weighted average of a and b, favoring b by x percent (so x==0 results in a, x==1 results in b) - Parameters:
-
| a | first value |
| b | second value |
| x | weight of second value as opposed to first |
- Returns:
- Todo:
- replace with a more fancy spline based thing?
Definition at line 153 of file MotionCommand.h.
Referenced by interpolate(). |
virtual bool MotionCommand::isActive |
( |
|
) |
const [inline, virtual] |
|
|
returns true if the MotionCommand is currently running (although it may be overridden by a higher priority MotionCommand)
Definition at line 130 of file MotionCommand.h. |
virtual int MotionCommand::isAlive |
( |
|
) |
[pure virtual] |
|
|
used to prune "dead" motions from the MotionManager
note that a motion could be "paused" or inactive and therefore not dirty, but still alive, biding its time to "strike" ;) - Returns:
- zero if the motion is still processing, non-zero otherwise
Implemented in DynamicMotionSequence, HeadPointerMC, LedMC, MotionSequenceMC< MAXMOVE >, OldHeadPointerMC, PIDMC, PostureMC, RemoteControllerMC, TailWagMC, UPennWalkMC, and WalkMC.
Referenced by shouldPrune(). |
virtual int MotionCommand::isDirty |
( |
|
) |
[pure virtual] |
|
|
not used by MotionManager at the moment, but could be used to reduce recomputation, and you may find it useful
- Returns:
- zero if none of the commands have changed since last getJointCmd(), else non-zero
Implemented in DynamicMotionSequence, HeadPointerMC, LedMC, MotionSequenceMC< MAXMOVE >, OldHeadPointerMC, PIDMC, PostureMC, RemoteControllerMC, TailWagMC, UPennWalkMC, and WalkMC. |
void MotionCommand::postEvent |
( |
const EventBase & |
event |
) |
[protected] |
|
|
calls EventTranslator::trapEvent() directly (avoids needing erouter, which is a non-shared global, causes problems with context, grr, silly OS)
Definition at line 8 of file MotionCommand.cc.
Referenced by WalkMC::DoStart(), WalkMC::DoStop(), EmergencyStopMC::freezeJoints(), EmergencyStopMC::releaseJoints(), WalkMC::updateOutputs(), PostureMC::updateOutputs(), OldHeadPointerMC::updateOutputs(), LedMC::updateOutputs(), and HeadPointerMC::updateOutputs(). |
virtual void MotionCommand::setAutoPrune |
( |
bool |
ap |
) |
[inline, virtual] |
|
|
only called from MMCombo during process setup, allows MotionCommands to send events
Definition at line 143 of file MotionCommand.h. |
virtual bool MotionCommand::shouldPrune |
( |
|
) |
[inline, virtual] |
|
virtual int MotionCommand::updateOutputs |
( |
|
) |
[pure virtual] |
|
|
is called once per update cycle, can do any processing you need to change your priorities or set output commands on the MotionManager
- Returns:
- zero if no changes were made, non-zero otherwise
- See also:
- RobotInfo::NumFrames
RobotInfo::FrameTime
Implemented in DynamicMotionSequence, EmergencyStopMC, HeadPointerMC, LedMC, MotionSequenceMC< MAXMOVE >, OldHeadPointerMC, PIDMC, PostureMC, RemoteControllerMC, TailWagMC, UPennWalkMC, WalkMC, and WaypointWalk< MAX_WAY >.
Referenced by MotionManager::getOutputs(). |
Member Data Documentation
The documentation for this class was generated from the following files:
|