Difference between revisions of "MCA2 Puma Tutorial Chapter 5"

From Mca2
Jump to navigationJump to search
(Simulating a complete Puma robot)
Line 7: Line 7:
 
== Create a group ==
 
== Create a group ==
  
The script newModule creates empty but useful module definitions. There is an equivalent script for groups, too: newGroup. Just type:
+
The script newModule creates empty but useful module definitions. There is an equivalent script for groups, too: new_group.py Just type:
  
  > newGroup project/puma PumaJoints
+
  > new_group.py -C projects/puma PumaJoints
  
 
in your MCA main directory.
 
in your MCA main directory.

Revision as of 11:18, 14 August 2009

GO BACK HOME

Simulating a complete Puma robot

A main feature of MCA is the possibility to combine individual modules to groups. These groups then act like any other individual module and can also be integrated into other more complex groups. In this chapter we will learn how to integrate our six joint simulation modules into one group, which then simulates a complete puma robot.

Create a group

The script newModule creates empty but useful module definitions. There is an equivalent script for groups, too: new_group.py Just type:

> new_group.py -C projects/puma PumaJoints

in your MCA main directory.

In the new header file gPumaJoints.h ("g" for "group") the necessary modules have to be included:

> //----------------------------------------------------------------------
> // Project Includes - include with ""
> //----------------------------------------------------------------------
> #include "mJointSimulation.h"

Additionally the IO definitions have to be added. We use a controller input and a sensor output for each included joint module:

>    /*!
>    Anonymous enumeration type which contains the indices of the
>    controller inputs.
>    */
>    _DESCR_( static, gPumaJoints::ci_description, 4, Natural, cDATA_VECTOR_END_MARKER );
>    enum {
>        eCI_WAIST,
>        eCI_SHOULDER,
>        eCI_ELBOW,
>        eCI_WRIST_ROT,
>        eCI_WRIST_BEND,
>        eCI_FLANGE,
>        eCI_DIMENSION /*!< Endmarker and Dimension */
>    };
>    /*!
>      Anonymous enumeration type which contains the indices of the
>      sensor outputs.
>     */
>    _DESCR_( static, gPumaJoints::so_description, 4, Natural, cDATA_VECTOR_END_MARKER );
>    enum {
>        eSO_WAIST,
>        eSO_SHOULDER,
>        eSO_ELBOW,
>        eSO_WRIST_ROT,
>        eSO_WRIST_BEND,
>        eSO_FLANGE,
>        eSO_DIMENSION /*!< Endmarker and Dimension */
>    };

The functions Control and Sense of groups are already implemented. They call the equivalent functions of the integrated modules in an iterative way. You as user only have to create modules or groups within the constructor and if necessary release used heap memory in the destructor. All modules that are integrated into a group are deleted automatically within the destructor of tModule .

In our case we have to create six instances of the module mJointSimulation in the constructor of gPumaJoints.C. Then the IOs of these modules have to be connected to the IOs of our group. AddEdge... commands are used to do this.

> gPumaJoints::gPumaJoints( tParent *parent, tDescription name, bool fixit )
>        : tGroup( parent, name,
>                  eSI_DIMENSION, eSO_DIMENSION, eCI_DIMENSION, eCO_DIMENSION,
>                  si_description, so_description, ci_description, co_description )
>{
>    // create module
>    mJointSimulation *waist = new mJointSimulation( this, "Waist" );
>    // Add Edges
>    AddEdgeDown( this, waist, 1, eCI_WAIST, mJointSimulation::eCI_DESIRED_JOINT_ANGLE );
>    AddEdgeUp( waist, this, 1, mJointSimulation::eSO_CURRENT_JOINT_ANGLE, eSO_WAIST );
>
>    mJointSimulation *shoulder = new mJointSimulation( this, "Shoulder" );
>    AddEdgeDown( this, shoulder, 1, eCI_SHOULDER, mJointSimulation::eCI_DESIRED_JOINT_ANGLE );
>    AddEdgeUp( shoulder, this, 1, mJointSimulation::eSO_CURRENT_JOINT_ANGLE, eSO_SHOULDER );
>
>    mJointSimulation *elbow = new mJointSimulation( this, "Elbow" );
>    AddEdgeDown( this, elbow, 1, eCI_ELBOW, mJointSimulation::eCI_DESIRED_JOINT_ANGLE );
>    AddEdgeUp( elbow, this, 1, mJointSimulation::eSO_CURRENT_JOINT_ANGLE, eSO_ELBOW );
>
>    mJointSimulation *wrist_rot = new mJointSimulation( this, "Wrist Rot" );
>    AddEdgeDown( this, wrist_rot, 1, eCI_WRIST_ROT, mJointSimulation::eCI_DESIRED_JOINT_ANGLE );
>    AddEdgeUp( wrist_rot, this, 1, mJointSimulation::eSO_CURRENT_JOINT_ANGLE, eSO_WRIST_ROT );
>
>    mJointSimulation *wrist_bend = new mJointSimulation( this, "Wrist Bend" );
>    AddEdgeDown( this, wrist_bend, 1, eCI_WRIST_BEND, mJointSimulation::eCI_DESIRED_JOINT_ANGLE );
>    AddEdgeUp( wrist_bend, this, 1, mJointSimulation::eSO_CURRENT_JOINT_ANGLE, eSO_WRIST_BEND );
>
>    mJointSimulation *flange = new mJointSimulation( this, "Flange" );
>    AddEdgeDown( this, flange, 1, eCI_FLANGE, mJointSimulation::eCI_DESIRED_JOINT_ANGLE );
>    AddEdgeUp( flange, this, 1, mJointSimulation::eSO_CURRENT_JOINT_ANGLE, eSO_FLANGE );
>
>    if ( fixit )
>        FixIt();
>}

In the above example we use one form of the AddEdge... functions. We define the from and to modules and the number of values that are to be copied. As our modules only have one value on each side, we connect only one. The last two parameters specify the index of the inputs and outputs to be connected.

Tip: Always take care to set the correct number of edges to be connected in the AddEdge... function. Otherwise either data is not transferred or a segfault might occur.