hekateros_control_main.cpp
Go to the documentation of this file.
00001 
00002 //
00003 // Package:   RoadNarrows Robotics Hekateros Robotic Manipulator ROS Package
00004 //
00005 // Link:      https://github.com/roadnarrows-robotics/hekateros
00006 //
00007 // ROS Node:  hekateros_control
00008 //
00009 // File:      hekateros_control_main.cpp
00010 //
00026 /*
00027  * @EulaBegin@
00028  * 
00029  * Permission is hereby granted, without written agreement and without
00030  * license or royalty fees, to use, copy, modify, and distribute this
00031  * software and its documentation for any purpose, provided that
00032  * (1) The above copyright notice and the following two paragraphs
00033  * appear in all copies of the source code and (2) redistributions
00034  * including binaries reproduces these notices in the supporting
00035  * documentation.   Substantial modifications to this software may be
00036  * copyrighted by their authors and need not follow the licensing terms
00037  * described here, provided that the new terms are clearly indicated in
00038  * all files where they apply.
00039  * 
00040  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
00041  * OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
00042  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
00043  * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
00044  * EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
00045  * THE POSSIBILITY OF SUCH DAMAGE.
00046  * 
00047  * THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
00048  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00049  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
00050  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
00051  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00052  * 
00053  * @EulaEnd@
00054  */
00056 
00057 //
00058 // System
00059 //
00060 #include <sys/types.h>
00061 #include <unistd.h>
00062 #include <signal.h>
00063 #include <string>
00064 
00065 //
00066 // ROS 
00067 //
00068 #include "ros/ros.h"
00069 
00070 //
00071 // RoadNarrows
00072 //
00073 #include "rnr/rnrconfig.h"
00074 #include "rnr/log.h"
00075 #include "rnr/opts.h"
00076 
00077 //
00078 // RoadNarrows embedded hekateros library.
00079 //
00080 #include "Hekateros/hekateros.h"
00081 
00082 //
00083 // Node headers.
00084 //
00085 #include "hekateros_control.h"
00086 #include "hekateros_as_calib.h"
00087 #include "hekateros_as_follow_traj.h"
00088 
00089 using namespace ::std;
00090 using namespace hekateros;
00091 using namespace hekateros_control;
00092 
00093 
00094 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
00095 // Node Specific Defines and Data
00096 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
00097 
00098 //
00099 // Application exit codes
00100 //
00101 #define APP_EC_OK   0   ///< success
00102 #define APP_EC_INIT 2   ///< initialization fatal error
00103 #define APP_EC_EXEC 4   ///< execution fatal error
00104 
00105 #define NO_SIGNAL   0   ///< no signal receieved value
00106 
00107 //
00108 // Data
00109 //
00110 const char *NodeName  = "hekateros_control";  
00111 static int  RcvSignal = NO_SIGNAL;            
00112 
00113 
00114 
00115 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
00116 // RoadNarrows Specific Defines and Data
00117 //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
00118 
00119 //
00120 // Options
00121 //
00122 static char  *OptsCfgFile     = (char *)HekEtcCfg;      
00123 static char  *OptsDevDynabus  = (char *)HekDevDynabus;  
00124 static int    OptsBaudDynabus = HekBaudRateDynabus;     
00125 static char  *OptsDevArduino  = (char *)HekDevArduino;  
00126 static int    OptsBaudArduino = HekBaudRateArduino;     
00127 
00134 static const PkgInfo_T PkgInfo =
00135 {
00136   NodeName,                       
00137   "1.1.0",                        
00138   "2014.03.17",                   
00139   "2014",                         
00140   NodeName,                       
00141   "Robin Knight, Daniel Packard", 
00142   "RoadNarrows LLC",              
00143   "(C) 2013-2014 RoadNarrows LLC" 
00144 };
00145 
00149 static OptsPgmInfo_T AppPgmInfo =
00150 {
00151   // usage_args
00152   "[ROSOPTIONS]",
00153 
00154   // synopsis
00155   "The %P ROS node provides ROS interfaces to the Hekateros robotic "
00156   "manipulator.",
00157   
00158   // long_desc 
00159   "",
00160  
00161   // diagnostics
00162   NULL
00163 };
00164 
00168 static OptsInfo_T AppOptsInfo[] =
00169 {
00170   // --config
00171   {
00172     "config",             // long_opt
00173     OPTS_NO_SHORT,        // short_opt
00174     required_argument,    // has_arg
00175     true,                 // has_default
00176     &OptsCfgFile,         // opt_addr
00177     OptsCvtArgStr,        // fn_cvt
00178     OptsFmtStr,           // fn_fmt
00179     "<file>",             // arg_name
00180     "Hekateros serial USB Dynamixel bus device name."
00181                           // opt desc
00182   },
00183 
00184   // --dynabus
00185   {
00186     "dynabus",            // long_opt
00187     OPTS_NO_SHORT,        // short_opt
00188     required_argument,    // has_arg
00189     true,                 // has_default
00190     &OptsDevDynabus,      // opt_addr
00191     OptsCvtArgStr,        // fn_cvt
00192     OptsFmtStr,           // fn_fmt
00193     "<device>",           // arg_name
00194     "Hekateros Dynamixel bus serial USB device name."
00195                           // opt desc
00196   },
00197 
00198   // --dynabus-baudrate
00199   {
00200     "dynabus-baudrate",   // long_opt
00201     OPTS_NO_SHORT,        // short_opt
00202     required_argument,    // has_arg
00203     true,                 // has_default
00204     &OptsBaudDynabus,     // opt_addr
00205     OptsCvtArgInt,        // fn_cvt
00206     OptsFmtInt,           // fn_fmt
00207     "<rate>",             // arg_name
00208     "Hekateros Dynamixel bus serial USB baud rate."
00209                           // opt desc
00210   },
00211 
00212   // --arduino
00213   {
00214     "arduino",            // long_opt
00215     OPTS_NO_SHORT,        // short_opt
00216     required_argument,    // has_arg
00217     true,                 // has_default
00218     &OptsDevArduino,      // opt_addr
00219     OptsCvtArgStr,        // fn_cvt
00220     OptsFmtStr,           // fn_fmt
00221     "<device>",           // arg_name
00222     "Hekateros Arduino monitor subprocessor serial USB device name."
00223                           // opt desc
00224   },
00225 
00226   // --arduino-baudrate
00227   {
00228     "arduino-baudrate",   // long_opt
00229     OPTS_NO_SHORT,        // short_opt
00230     required_argument,    // has_arg
00231     true,                 // has_default
00232     &OptsBaudArduino,     // opt_addr
00233     OptsCvtArgInt,        // fn_cvt
00234     OptsFmtInt,           // fn_fmt
00235     "<rate>",             // arg_name
00236     "Hekateros Arduino monitor subprocessor serial USB baud rate."
00237                           // opt desc
00238   },
00239 
00240   {NULL, }
00241 };
00242 
00250 static void sigHandler(int sig)
00251 {
00252   RcvSignal = sig;
00253 
00254   // All the default sigint handler does is call shutdown()
00255   //ros::shutdown();
00256 }
00257 
00266 int main(int argc, char *argv[])
00267 {
00268   string  strNodeName;    // ROS-given node name
00269   double  hz = 30;        // ROS loop rate
00270   int     rc;             // return code
00271 
00272   // 
00273   // Initialize the node. Parse the command line arguments and environment to
00274   // determine ROS options such as node name, namespace and remappings.
00275   // This call does not contact the master. This lets you use
00276   // ros::master::check() and other ROS functions after calling ros::init()
00277   // to check on the status of the master.
00278   //
00279   ros::init(argc, argv, NodeName);
00280 
00281   //
00282   // Parse node-specific options and arguments (from librnr).
00283   //
00284   OptsGet(NodeName, &PkgInfo, &AppPgmInfo, AppOptsInfo, true, &argc, argv);
00285  
00286   //
00287   //
00288   // A ctrl-c interrupt will stop attempts to connect to the ROS core.
00289   //
00290   ros::NodeHandle nh(NodeName);
00291 
00292   // actual ROS-given node name
00293   strNodeName = ros::this_node::getName();
00294 
00295   //
00296   // Failed to connect.
00297   //
00298   if( !ros::master::check() )
00299   {
00300     // add optional non-ROS unit tests here, then simply exit.
00301     return APP_EC_OK;
00302   }
00303 
00304   ROS_INFO("%s: Node started.", strNodeName.c_str());
00305   
00306   //
00307   // Create a hekateros node object.
00308   //
00309   HekaterosControl  hek(nh, hz);
00310 
00311   //
00312   // Load and parse configuration file.
00313   //
00314   if( (rc = hek.configure(OptsCfgFile)) != HEK_OK )
00315   {
00316     ROS_FATAL_STREAM(strNodeName
00317         << ": Failed to load configuration file "
00318         << OptsCfgFile);
00319     return APP_EC_INIT;
00320   }
00321 
00322   //
00323   // Connect to the Hekateros.
00324   //
00325   while( (rc = hek.connect(OptsDevDynabus, OptsBaudDynabus,
00326                            OptsDevArduino, OptsBaudArduino)) != HEK_OK )
00327   {
00328     ROS_ERROR_STREAM(strNodeName << ": Failed to connect to Hekateros.");
00329     sleep(5);
00330     //return APP_EC_INIT;
00331   }
00332 
00333   //
00334   // Signals
00335   //
00336 
00337   // Override the default ros sigint handler. This must be set after the first
00338   // NodeHandle is created.
00339   signal(SIGINT, sigHandler);
00340 
00341   // try to end safely with this signal
00342   signal(SIGTERM, sigHandler);
00343 
00344   //
00345   // Advertise services.
00346   //
00347   hek.advertiseServices();
00348 
00349   ROS_INFO("%s: Services registered.", strNodeName.c_str());
00350 
00351   //
00352   // Advertise publishers.
00353   //
00354   hek.advertisePublishers();
00355   
00356   ROS_INFO("%s: Publishers registered.", strNodeName.c_str());
00357   
00358   //
00359   // Subscribed to topics.
00360   //
00361   hek.subscribeToTopics();
00362   
00363   ROS_INFO("%s: Subscribed topics registered.", strNodeName.c_str());
00364 
00365   //
00366   // Create Action Servers
00367   //
00368   ASCalibrate         asCalib("calibrate_as", hek);
00369   ASFollowTrajectory  asFollowTrajectory("follow_joint_traj_as", hek);
00370 
00371   ROS_INFO("%s: Action servers created.", strNodeName.c_str());
00372 
00373   // set loop rate in Hertz
00374   ros::Rate loop_rate(hz);
00375 
00376   ROS_INFO("%s: Ready.", strNodeName.c_str());
00377   ROS_WARN("Hekateros requires calibration:\n"
00378            " -- Please put Hekateros in a safe position before calibrating.\n"
00379            " -- See user manual: \"Calibrating Hekateros\" for guidance.");
00380 
00381   //
00382   // Main loop.
00383   //
00384   while( (RcvSignal == NO_SIGNAL) && ros::ok() )
00385   {
00386     // make any callbacks on pending ROS events
00387     ros::spinOnce(); 
00388 
00389     // publish all advertized topics
00390     hek.publish();
00391 
00392     // sleep to keep at loop rate
00393     loop_rate.sleep();
00394   }
00395 
00396   return APP_EC_OK;
00397 }


hekateros_control
Author(s): Robin Knight , Daniel Packard
autogenerated on Mon Oct 6 2014 00:36:42