Problem: How to reuse a component when you need the ports to have different names?
Solution: Name the connection between ports in the deployer. This essentially allows you to rename ports. Unfortunately, this extremely useful feature is not documented anywhere (as of July, 2009). <!-- break -->
Problem: How to reuse a component when you need the ports to have different names?
Solution: Name the connection between ports in the deployer. This essentially allows you to rename ports. Unfortunately, this extremely useful feature is not documented anywhere (as of July, 2009). <!-- break -->
This example occurs in three parts
class HMI : public RTT::TaskContext { protected: // *** OUTPUTS *** /// desired cartesian position RTT::WriteDataPort<KDL::Frame> cartesianPosition_desi_port; public: HMI(std::string name); virtual ~HMI(); protected: /// set the desired cartesian position to an initial value /// \return true virtual bool startHook(); };
class Robot : public RTT::TaskContext { protected: // *** INPUTS *** /// desired cartesian position RTT::ReadDataPort<KDL::Frame> cartesianPosition_desi_port; public: Robot(std::string name); virtual ~Robot(); };
class OneAxisFilter : public RTT::TaskContext { protected: // *** INPUTS *** /// desired cartesian position RTT::ReadDataPort<KDL::Frame> inputPosition_port; // *** OUTPUTS *** /// desired cartesian position RTT::WriteDataPort<KDL::Frame> outputPosition_port; // *** CONFIGURATION *** /// specify which axis to filter (should be one of "x", "y", or "z") RTT::Property<std::string> axis_prop; public: OneAxisFilter(std::string name); virtual ~OneAxisFilter(); protected: /// validate axis_prop value /// \return true if axis_prop value is valid, otherwise false virtual bool configureHook(); /// filter one translational axis (as specified by axis_prop) virtual void updateHook(); };
The component implementations are not given in this example, as they are not the interesting part of the solution, but are available in the Files section above.
The interesting part is in the deployment files ...
This part simply connects the HMI and robot together (see deployment file Connect-1.xml).
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "cpf.dtd"> <properties> <simple name="Import" type="string"> <value>liborocos-rtt</value> </simple> <simple name="Import" type="string"> <value>liborocos-kdl</value> </simple> <simple name="Import" type="string"> <value>liborocos-kdltk</value> </simple> <simple name="Import" type="string"> <value>libConnectionNaming</value> </simple>
<struct name="HMI" type="HMI"> <struct name="Activity" type="PeriodicActivity"> <simple name="Period" type="double"><value>0.5</value></simple> <simple name="Priority" type="short"><value>0</value></simple> <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple> </struct> <simple name="AutoConf" type="boolean"><value>1</value></simple> <simple name="AutoStart" type="boolean"><value>1</value></simple> <struct name="Ports" type="PropertyBag"> <simple name="cartesianPosition_desi" type="string"> <value>cartesianPosition_desi</value></simple> </struct> </struct>
<simple name="portName" type="string"> <value>connectionName</value> </simple>
<struct name="Robot" type="Robot"> <struct name="Activity" type="PeriodicActivity"> <simple name="Period" type="double"><value>0.5</value></simple> <simple name="Priority" type="short"><value>0</value></simple> <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple> </struct> <simple name="AutoConf" type="boolean"><value>1</value></simple> <simple name="AutoStart" type="boolean"><value>1</value></simple> <struct name="Peers" type="PropertyBag"> <simple type="string"><value>HMI</value></simple> </struct> <struct name="Ports" type="PropertyBag"> <simple name="cartesianPosition_desi" type="string"> <value>cartesianPosition_desi</value></simple> </struct> </struct> </properties>
Now, the deployer uses connection names when connecting components between peers, not port names. So it attempts to connect a Robot.cartesianPosition_desi connection to a Vehicle. cartesianPosition_desi connection (which in this part, matches the port names).
Build the library, and then run this part with
cd /path/to/ConnectionNaming/build deployer-macosx -s ../Connect-1.xml
Examine the HMI and Robot components, and note that each has a connected port, and the port values match.
This part adds a filter component between the HMI and the robot (see Connect-2.xml)
As with Part 1, the first part of the file loads the appropriate libraries (left out here, as it is identical to Part 1).
<struct name="HMI" type="HMI"> <struct name="Activity" type="PeriodicActivity"> <simple name="Period" type="double"><value>0.5</value></simple> <simple name="Priority" type="short"><value>0</value></simple> <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple> </struct> <simple name="AutoConf" type="boolean"><value>1</value></simple> <simple name="AutoStart" type="boolean"><value>1</value></simple> <struct name="Ports" type="PropertyBag"> <simple name="cartesianPosition_desi" type="string"> <value>unfiltered_cartesianPosition_desi</value></simple> </struct> </struct>
<struct name="Filter" type="OneAxisFilter"> <struct name="Activity" type="PeriodicActivity"> <simple name="Period" type="double"><value>0.5</value></simple> <simple name="Priority" type="short"><value>0</value></simple> <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple> </struct> <simple name="AutoConf" type="boolean"><value>1</value></simple> <simple name="AutoStart" type="boolean"><value>1</value></simple> <struct name="Peers" type="PropertyBag"> <simple type="string"><value>HMI</value></simple> </struct> <struct name="Ports" type="PropertyBag"> <simple name="inputPosition" type="string"> <value>unfiltered_cartesianPosition_desi</value></simple> <simple name="outputPosition" type="string"> <value>filtered_cartesianPosition_desi</value></simple> </struct> <simple name="PropertyFile" type="string"> <value>../Filter1.cpf</value></simple> </struct>
<struct name="Robot" type="Robot"> <struct name="Activity" type="PeriodicActivity"> <simple name="Period" type="double"><value>0.5</value></simple> <simple name="Priority" type="short"><value>0</value></simple> <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple> </struct> <simple name="AutoConf" type="boolean"><value>1</value></simple> <simple name="AutoStart" type="boolean"><value>1</value></simple> <struct name="Peers" type="PropertyBag"> <simple type="string"><value>Filter</value></simple> </struct> <struct name="Ports" type="PropertyBag"> <simple name="cartesianPosition_desi" type="string"> <value>filtered_cartesianPosition_desi</value></simple> </struct> </struct>
Run this part with
cd /path/to/ConnectionNaming/build deployer-macosx -s ../Connect-2.xml
Examine all three components, and note that all ports are connected, and in particular, that the HMI and Filter.inputPosition ports match while the Filter.outputPosition and Vehicle ports match (ie they have the 'x' axis filtered out).
Using connection naming allows us to connect ports of different names. This is particularly useful with a generic component like this filter, as in one deployment it may connect to a component with ports named cartesianPosition_desi, while in another deployment it may connect to ports named CartDesiPos, or any other names. The filter component is now decoupled from the actual port names used to deploy it.
This part adds a second filter between the first filter and the robot.
As with Parts 1 and 2, the libraries are loaded first.
<struct name="HMI" type="HMI"> <struct name="Activity" type="PeriodicActivity"> <simple name="Period" type="double"><value>0.5</value></simple> <simple name="Priority" type="short"><value>0</value></simple> <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple> </struct> <simple name="AutoConf" type="boolean"><value>1</value></simple> <simple name="AutoStart" type="boolean"><value>1</value></simple> <struct name="Ports" type="PropertyBag"> <simple name="cartesianPosition_desi" type="string"> <value>unfiltered_cartesianPosition_desi</value></simple> </struct> </struct>
<struct name="Filter1" type="OneAxisFilter"> <struct name="Activity" type="PeriodicActivity"> <simple name="Period" type="double"><value>0.5</value></simple> <simple name="Priority" type="short"><value>0</value></simple> <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple> </struct> <simple name="AutoConf" type="boolean"><value>1</value></simple> <simple name="AutoStart" type="boolean"><value>1</value></simple> <struct name="Peers" type="PropertyBag"> <simple type="string"><value>HMI</value></simple> </struct> <struct name="Ports" type="PropertyBag"> <simple name="inputPosition" type="string"> <value>unfiltered_cartesianPosition_desi</value></simple> <simple name="outputPosition" type="string"> <value>filtered_cartesianPosition_desi</value></simple> </struct> <simple name="PropertyFile" type="string"> <value>../Filter1.cpf</value></simple> </struct>
<struct name="Filter2" type="OneAxisFilter"> <struct name="Activity" type="PeriodicActivity"> <simple name="Period" type="double"><value>0.5</value></simple> <simple name="Priority" type="short"><value>0</value></simple> <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple> </struct> <simple name="AutoConf" type="boolean"><value>1</value></simple> <simple name="AutoStart" type="boolean"><value>1</value></simple> <struct name="Peers" type="PropertyBag"> <simple type="string"><value>HMI</value></simple> </struct> <struct name="Ports" type="PropertyBag"> <simple name="inputPosition" type="string"> <value>filtered_cartesianPosition_desi</value></simple> <simple name="outputPosition" type="string"> <value>double_filtered_cartesianPosition_desi</value></simple> </struct> <simple name="PropertyFile" type="string"> <value>../Filter2.cpf</value></simple> </struct>
<struct name="Robot" type="Robot"> <struct name="Activity" type="PeriodicActivity"> <simple name="Period" type="double"><value>0.5</value></simple> <simple name="Priority" type="short"><value>0</value></simple> <simple name="Scheduler" type="string"><value>ORO_SCHED_OTHER</value></simple> </struct> <simple name="AutoConf" type="boolean"><value>1</value></simple> <simple name="AutoStart" type="boolean"><value>1</value></simple> <struct name="Peers" type="PropertyBag"> <simple type="string"><value>Filter2</value></simple> </struct> <struct name="Ports" type="PropertyBag"> <simple name="cartesianPosition_desi" type="string"> <value>double_filtered_cartesianPosition_desi</value></simple> </struct> </struct>
Run this part with
cd /path/to/ConnectionNaming/build deployer-macosx -s ../Connect-3.xml
Examine all components, and note which ports are connected, and what their values are. Note that the vehicle has two axes knocked out (x and y).
In a shell
cd /path/to/ConnectionNaming mkdir build cd build cmake .. -DOROCOS_TARGET=macosx make
For other operating systems substitute the appopriate value for "macosx" when setting OROCOS_TARGET (e.g. "gnulinux").
Tested in Mac OS X Leopard 10.5.7.
Attachment | Size |
---|---|
HMI.hpp | 2.16 KB |
Robot.hpp | 1.99 KB |
OneAxisFilter.hpp | 2.52 KB |
HMI.cpp | 2.04 KB |
Robot.cpp | 1.94 KB |
OneAxisFilter.cpp | 2.92 KB |
Connect-1.xml | 1.96 KB |
Connect-2.xml | 2.91 KB |
Connect-3.xml | 3.85 KB |
connectionNaming.tar_.bz2 | 7.01 KB |