www.it-ebooks.info
Chapter 7: Using Orchestration Services to Build a Simulation Scenario
{
// all the cones have been visited _endTime = DateTime.Now;
}
break;
}
After that, it checks whether all the cones have been touched. If so, the robot enters the Finished state. Otherwise, it returns to the Wander state to find more cones.
The Finished State
The Finished state simply causes the robot to spin around in wild celebration until you click the Reset button to try the scenario again:
case ModeType.Finished:
if (!driveCommandFailed)
yield return Arbiter.Choice( _drivePort.RotateDegrees(180, _rotateSpeed), delegate(DefaultUpdateResponseType response) { }, delegate(Fault f) { driveCommandFailed = true; }
);
break;
The Avoid Collision State
The only state that hasn’t been described yet is the AvoidCollision state. Right now, this state does the same thing regardless of where the obstacle lies. It would be a great improvement if the robot did more discovery to determine the direction to drive to actually avoid the obstacle, rather than blunder around:
case ModeType.AvoidCollision:
{
// back away
if (!driveCommandFailed)
yield return Arbiter.Choice( _drivePort.DriveDistance(-0.25, _driveSpeed), delegate(DefaultUpdateResponseType response) { }, delegate(Fault f) { driveCommandFailed = true; }
);
// turn left
if (!driveCommandFailed)
yield return Arbiter.Choice( _drivePort.RotateDegrees(90, _rotateSpeed), delegate(DefaultUpdateResponseType response) { }, delegate(Fault f) { driveCommandFailed = true; }
);
_state.CurrentMode = ModeType.Wander;
(continued)
www.it-ebooks.info
Part II: Simulations
(continued)
// move forward
if (!driveCommandFailed)
yield return Arbiter.Choice( _drivePort.DriveDistance(1, _driveSpeed), delegate(DefaultUpdateResponseType response) { }, delegate(Fault f) { driveCommandFailed = true; }
);
break;
}
As you can see from the implementation, when the robot detects an impending collision, it backs up a quarter meter, turns 90 degrees to the left, changes to Wander mode, and then drives forward one meter.
Add the state implementations just discussed to your code, along with the GetHappiness method and its associated variables, and your SimMagellan service is complete.
Using the SimMagellan Service
Once you click Reset and Start, the service runs itself. You will probably have to move the MainCamera around a bit to keep the Corobot in view, and you’ll definitely want to be watching the SimMagellan user interface form to see the results of the image processing and the current state of the robot. The elapsed time gives you a good measure of your algorithm’s efficiency, although the same algorithm can have radically different execution times as a result of very small variations in the robot’s behavior. Each time you enhance the robot behavior, measure the elapsed time of a few runs to determine the amount of improvement you have achieved.
Don’t forget that you can use the Simulation Editor to select the Corobot entity and move it around in the environment. This can come in handy if it happens to hit a wall on the edge and flip over or if you just want to see how it handles a particular approach to a cone.
Future Directions
There are several things you can do with this simulation scenario to make it more like the actual SRS Robo-Magellan competition. For one thing, very few robot drives can report back on their actual position in the world. You should implement a simulated GPS entity and associated service that returns the position of the robot in latitude and longitude. Such a simulated service should probably also provide a way to model areas of poor reception in the world so that the navigation algorithm can handle these properly.
Another improvement to this simulation would be to change the happiness function to make the robot traverse the cones in a particular order. In the current simulation, the order in which the robot visits the cones is unimportant. One simple way to make the obstacle avoidance more efficient is to add waypoints with a negative happiness to the list each time an obstacle is encountered. This would keep the robot from moving toward an area where there is a known obstacle.
Finally, the obstacles in the environment are currently fairly simple. It is fairly easy to reconfigure the environment in the Referee service or to even have several canned environments that can be easily selected. A good navigation algorithm should be able to handle a variety of environments.
www.it-ebooks.info
Chapter 7: Using Orchestration Services to Build a Simulation Scenario
Summary
Congratulations! Between this chapter and the last one, you have covered quite a bit of territory, not to mention nearly 3500 lines of code.
In this chapter, you built on the entities and services defined in the last chapter to create a complete scenario. A Referee service initialized the environment with trigger cones, barriers, and a single Corobot. Finally, you defined the Robo-Magellan orchestration service, complete with a Windows Forms user interface and a robot behavior model sufficient to navigate the course.
Having conquered the world of wheeled robots for the time being, you’ll now move on to robotic arms and articulated robots in the next chapter.
www.it-ebooks.info
Simulating Articulated
Entities
This chapter explains how to create articulated entities such as robotic arms and jointed robots in the simulation environment. Wheeled robots are fine for some applications, but sometimes you need a robot that can reach out and grab things.
The primary mechanism for defining articulated entities is the Joint object. This chapter begins by describing how to use a joint to join two entities and all of the options that are available. Then you will learn how to build a robotic arm with multiple joints.
The Joint Class
A Joint is an object that joins two entities together. It has up to six degrees of freedom (three angular and three linear), which means it can be configured in a number of different ways. The simplest joint is a revolute joint, which has a single angular degree of freedom unlocked, and it behaves much like a door hinge. A joint with a single linear degree of freedom unlocked would operate somewhat like a shock absorber or a worm gear, with the joined entities able to move closer or farther along a single direction. A joint with all degrees of freedom unlocked can move in any direction and rotate and twist into any possible orientation.
The Joint class is defined in the Microsoft.Robotics.PhysicalModel namespace, which is implemented in the RoboticsCommon DLL. This Joint class is available for all services to use, not just simulation services. Its most important member is the JointProperties member called State. These properties specify the behavior of the joint when it is created in the physics engine.
A subclass of the Joint class called PhysicsJoint is defined in the Microsoft.Robotics
.Simulation.Physics namespace, which is implemented in the PhysicsEngine DLL. This object contains some additional data that is used by the physics engine; it also includes some additional
www.it-ebooks.info
Part II: Simulations
methods. This is the object you must use when interacting with the physics engine. It is simple to convert a Joint object to a PhysicsJoint object and back again, as you’ll see in the example code in this chapter.
The Joint Frame
Before you look in detail at the JointProperties class, it is important to understand the joint frame. A frame is a set of three axes that represent one coordinate system relative to another. This concept should be familiar to those readers who have worked with computer graphics. In a typical graphics scene, each object has its own frame relative to the world coordinates that determines its position and orientation. In graphics coordinates, we usually label the three axes in a frame as the X axis, the Y axis, and the Z axis.
Frames are used to specify the orientation of a joint as well. The three axes in a joint frame are called the local axis, the normal axis, and the binormal axis, as shown in Figure 8-1.
Normal Axis
Swing 1
Local Axis
Binormal Axis
Twist
Swing 2
Figure 8-1
The joint frame follows the right-handed convention, meaning positive rotations around each axis are in the direction the fingers on your right hand curl when your thumb is pointed along the positive axis. The frame may be completely defined by specifying only two of the axes because the axes are always at right angles to each other and the third axis can be constructed by taking the cross product of the other two.
The joint names each angular degree of freedom (DOF), as shown in Figure 8-1. The Twist DOF is associated with rotations around the local axis, the Swing1 DOF is associated with rotations around the normal axis, and the Swing2 DOF is associated with rotations around the binormal axis.
Joint Properties
The joint properties define how the joint behaves and how it attaches to the entities it joins. A joint may contain a reference to a JointAngularProperties class to unlock one or more angular degrees of freedom. It may also contain a reference to a JointLinearProperties class to unlock one or more
www.it-ebooks.info
Chapter 8: Simulating Articulated Entities
linear degrees of freedom. It must always contain a two-element array of EntityJointConnector references to specify how it attaches to each entity.
The following sections describe the various members of the JointAngularProperties class, the
JointLinearProperties class, the EntityJointConnector class, and other associated classes. These properties are explored in more detail in sample code following the descriptions.
JointAngularProperties
The following table lists the members of the JointAngularProperties class:
Member |
Description |
|
|
TwistMode |
This member defines the mode for the Twist DOF, either |
|
locked, limited, or free. If locked, the joint is not free to move |
|
around the local axis. If limited, the rotation of the joint around |
|
the local axis is constrained by the UpperTwistLimit and the |
|
LowerTwistLimit. If free, the joint can move freely around |
|
the local axis. |
Swing1Mode |
Defines the mode for the Swing1 DOF as above. If limited, the |
|
rotation of the joint around the normal axis is constrained by |
|
the Swing1Limit. |
Swing2Mode |
Defines the mode for the Swing2 DOF as above. If limited, the |
|
rotation of the joint around the binormal axis is constrained by |
|
the Swing2Limit. |
UpperTwistLimit and |
JointLimitProperties that limit the motion of the joint |
LowerTwistLimit |
around the local axis |
Swing1Limit |
JointLimitProperties that limit the motion of the joint |
|
around the normal axis |
Swing2Limit |
JointLimitProperties that limit the motion of the joint |
|
around the binormal axis |
TwistDrive |
JointDriveProperties that define how the joint is driven |
|
around the local axis |
SwingDrive |
JointDriveProperties that define how the joint is driven |
|
around the swing axis |
SlerpDrive |
A spherical linear interpolation JointDriveProperties that |
|
defines a special way to drive three angular DOF joints. |
GearRatio |
If this member is nonzero, then the angular velocity of the |
|
second entity is driven toward the angular velocity of the first |
|
entity multiplied by the GearRatio. |
DriveTargetOrientation |
The initial orientation of the joint |
DriveTargetVelocity |
The initial angular velocity of the joint |
|
|
www.it-ebooks.info
Part II: Simulations
JointLimitProperties
The following table lists the members of the JointLimitProperties class:
Member |
Description |
|
|
LimitThreshold |
Specifies the angular or linear limit for the joint. Angular limits are |
|
expressed in radians. |
Restitution |
Floating-point value that specifies the “bounciness” of the joint as it |
|
moves against the limit |
Spring |
Spring properties that define a “soft limit.” If the SpringCoefficient |
|
is nonzero, the joint can travel through the limit threshold but the spring |
|
brings it back to the threshold. The DamperCoefficient specifies |
|
how much the spring oscillates as it brings the joint back to the |
|
LimitThreshold. |
|
|
JointDriveProperties
The following table lists the members of the JointDriveProperties class:
Member |
Description |
|
|
Mode |
Specifies the mode of driving this DOF. Position means that the joint is driven |
|
toward a specific position. Velocity means that the joint is driven toward a |
|
specific angular velocity. |
Spring |
Specifies the spring and damping coefficients for a spring that pulls the joint |
|
back to the target position |
ForceLimit |
Specifies the maximum force (torque) that the joint can exert to move to its |
|
target position |
|
|
JointLinearProperties
The following table lists the members of the JointLinearProperties class:
Member |
Description |
|
|
DriveTargetPosition, |
The initial target position and velocity for the linear degrees of |
DriveTargetVelocity |
freedom for the joint |
XMotionMode, |
The DOF mode for each linear degree of freedom: locked, limited, or |
YMotionMode, |
free. If limited, the motion of the joint along each axis is constrained |
ZMotionMode |
by the MotionLimit member. The XMotionMode specifies movement |
|
along the local axis. The YMotionMode specifies movement along the |
|
normal axis, and the ZMotionMode specifies movement along the |
|
binormal axis. |
|
|
|
|
www.it-ebooks.info |
|
|
Chapter 8: Simulating Articulated Entities |
|
|
|
|
|
|
Member |
Description |
|
|
|
|
|
|
XDrive, YDrive, |
The drive characteristics of the joint along each of the respective axes |
|
|
ZDrive |
|
|
|
MotionLimit |
Only a single JointLimitProperties member is provided for all |
|
|
|
three linear degrees of freedom. The LimitThreshold of the |
|
|
|
MotionLimit member specifies the maximum of the absolute value of |
|
|
|
the motion allowed along each linear axis. For example, if all three |
|
|
|
linear DOFs are limited, then the LimitThreshold of the |
|
|
|
MotionLimit member defines a radius of a sphere in which the |
|
|
|
anchor of the second entity is constrained to move about the anchor of |
|
|
|
the first entity. |
|
|
|
|
|
EntityJointConnector
The joint is anchored to each entity at a point and orientation specified by an EntityJointConnector, which has the following members:
Member |
Description |
|
|
JointAxis |
This is the vector that defines the local axis of the joint. It is often the |
|
vector (1,0,0) but it can be any vector. |
JointNormal |
This is the vector that defines the normal axis of the joint. It is often the |
|
vector (0,1,0) but it can be any vector that is perpendicular to |
|
theJointAxis vector. The binormal axis is the cross product of the |
|
JointAxis and the JointNormal. |
JointConnectPoint |
This is the point at which the joint attaches to the entity. It is in |
|
coordinates that are relative to the entity, not in world coordinates. |
|
The point doesn’t actually have to be on the surface of the entity, it can |
|
be inside the entity or some distance away. |
Entity |
This is a reference to the entity that is connected. When the joint is |
|
serialized, this field cannot be serialized correctly. Prior to serialization, |
|
the name of this entity must be written to the EntityName property, |
|
which does serialize properly. After deserialization, this Entity |
|
reference must be restored by finding the entity with the specified |
|
name. |
EntityName |
This is the name of the entity referenced by the Entity property. Its |
|
value is only used after deserialization to restore the Entity reference. |
|
|
www.it-ebooks.info
Part II: Simulations
JointProperties
The following table lists the members of the JointProperties class:
Member |
Description |
|
|
Connectors |
An array of two EntityJointConnectors that specifies the connection |
|
point and orientation for the first entity and the second entity |
Angular |
A reference to a JointAngularProperties class that specifies the |
|
angular properties for the joint. If this reference is null, then all angular |
|
degrees of freedom are considered locked. |
Linear |
A reference to a JointLinearProperties class that specifies the linear |
|
properties for the joint. If this reference is null, then all linear degrees of |
|
freedom are considered locked. |
EnableCollisions |
This Boolean property specifies whether collision detection checks |
|
should be performed between the entities connected by this joint |
MaximumForce, |
This is the maximum force or torque that can be applied to the joint. If |
MaximumTorque |
these limits are exceeded, the joint “breaks” and ceases to function. |
|
They should be set to similar values, and setting them to 0 ensures that the |
|
joint will never break. |
Name |
The name of the joint. Each joint should have a unique name. |
Projection |
The physics engine provides a way to correct large joint errors by |
|
projecting the joint back to a valid configuration. Joint errors occur |
|
when a joint’s constrain is violated — for example, a joint is forced to |
|
move beyond its joint limit. There are normally some small joint errors |
|
due to the imprecise nature of floating-point math and numerical |
|
integrators, and the physics engine compensates for these by applying |
|
small corrective forces. If a joint error becomes very large, joint |
|
projection can allow the physics engine to directly change the position |
|
of the joint to reduce the error. If you wish to enable joint projection, the |
|
AGEIA documentation suggests that you set the JointProjectionMode |
|
to PointMinimumDistance, the ProjectionAngleThreshold to |
|
0.0872, and the ProjectionDistanceThreshold to 0.1. |
|
|
A Joint TestBench
The best way to gain a good understanding of these various joint properties is to build a sample program that creates a variety of joints with various properties to see how they work.
Open the Chapter 8 solution in ProMRDS\Chapter8 and then open the TestBench.cs file in the TestBench project. This TestBench service is a basic simulation service much like Simulation Tutorial 1