00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00056
00057
00058
00059
00060 #include <sys/types.h>
00061 #include <unistd.h>
00062 #include <signal.h>
00063 #include <string>
00064
00065
00066
00067
00068 #include "ros/ros.h"
00069
00070
00071
00072
00073 #include "rnr/rnrconfig.h"
00074 #include "rnr/log.h"
00075 #include "rnr/opts.h"
00076
00077
00078
00079
00080 #include "Hekateros/hekateros.h"
00081
00082
00083
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
00096
00097
00098
00099
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
00109
00110 const char *NodeName = "hekateros_control";
00111 static int RcvSignal = NO_SIGNAL;
00112
00113
00114
00115
00116
00117
00118
00119
00120
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
00152 "[ROSOPTIONS]",
00153
00154
00155 "The %P ROS node provides ROS interfaces to the Hekateros robotic "
00156 "manipulator.",
00157
00158
00159 "",
00160
00161
00162 NULL
00163 };
00164
00168 static OptsInfo_T AppOptsInfo[] =
00169 {
00170
00171 {
00172 "config",
00173 OPTS_NO_SHORT,
00174 required_argument,
00175 true,
00176 &OptsCfgFile,
00177 OptsCvtArgStr,
00178 OptsFmtStr,
00179 "<file>",
00180 "Hekateros serial USB Dynamixel bus device name."
00181
00182 },
00183
00184
00185 {
00186 "dynabus",
00187 OPTS_NO_SHORT,
00188 required_argument,
00189 true,
00190 &OptsDevDynabus,
00191 OptsCvtArgStr,
00192 OptsFmtStr,
00193 "<device>",
00194 "Hekateros Dynamixel bus serial USB device name."
00195
00196 },
00197
00198
00199 {
00200 "dynabus-baudrate",
00201 OPTS_NO_SHORT,
00202 required_argument,
00203 true,
00204 &OptsBaudDynabus,
00205 OptsCvtArgInt,
00206 OptsFmtInt,
00207 "<rate>",
00208 "Hekateros Dynamixel bus serial USB baud rate."
00209
00210 },
00211
00212
00213 {
00214 "arduino",
00215 OPTS_NO_SHORT,
00216 required_argument,
00217 true,
00218 &OptsDevArduino,
00219 OptsCvtArgStr,
00220 OptsFmtStr,
00221 "<device>",
00222 "Hekateros Arduino monitor subprocessor serial USB device name."
00223
00224 },
00225
00226
00227 {
00228 "arduino-baudrate",
00229 OPTS_NO_SHORT,
00230 required_argument,
00231 true,
00232 &OptsBaudArduino,
00233 OptsCvtArgInt,
00234 OptsFmtInt,
00235 "<rate>",
00236 "Hekateros Arduino monitor subprocessor serial USB baud rate."
00237
00238 },
00239
00240 {NULL, }
00241 };
00242
00250 static void sigHandler(int sig)
00251 {
00252 RcvSignal = sig;
00253
00254
00255
00256 }
00257
00266 int main(int argc, char *argv[])
00267 {
00268 string strNodeName;
00269 double hz = 30;
00270 int rc;
00271
00272
00273
00274
00275
00276
00277
00278
00279 ros::init(argc, argv, NodeName);
00280
00281
00282
00283
00284 OptsGet(NodeName, &PkgInfo, &AppPgmInfo, AppOptsInfo, true, &argc, argv);
00285
00286
00287
00288
00289
00290 ros::NodeHandle nh(NodeName);
00291
00292
00293 strNodeName = ros::this_node::getName();
00294
00295
00296
00297
00298 if( !ros::master::check() )
00299 {
00300
00301 return APP_EC_OK;
00302 }
00303
00304 ROS_INFO("%s: Node started.", strNodeName.c_str());
00305
00306
00307
00308
00309 HekaterosControl hek(nh, hz);
00310
00311
00312
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
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
00331 }
00332
00333
00334
00335
00336
00337
00338
00339 signal(SIGINT, sigHandler);
00340
00341
00342 signal(SIGTERM, sigHandler);
00343
00344
00345
00346
00347 hek.advertiseServices();
00348
00349 ROS_INFO("%s: Services registered.", strNodeName.c_str());
00350
00351
00352
00353
00354 hek.advertisePublishers();
00355
00356 ROS_INFO("%s: Publishers registered.", strNodeName.c_str());
00357
00358
00359
00360
00361 hek.subscribeToTopics();
00362
00363 ROS_INFO("%s: Subscribed topics registered.", strNodeName.c_str());
00364
00365
00366
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
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
00383
00384 while( (RcvSignal == NO_SIGNAL) && ros::ok() )
00385 {
00386
00387 ros::spinOnce();
00388
00389
00390 hek.publish();
00391
00392
00393 loop_rate.sleep();
00394 }
00395
00396 return APP_EC_OK;
00397 }