FmkRobotROSBridge.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00007 #include "FmkRobotROSBridge.h"
00008 // Module specification
00009 // <rtc-template block="module_spec">
00010 static const char* fmkrobotrosbridge_spec[] =
00011   {
00012     "implementation_id", "FmkRobotROSBridge",
00013     "type_name",         "FmkRobotROSBridge",
00014     "description",       "VehicleService",
00015     "version",           "1.0.0",
00016     "vendor",            "",
00017     "category",          "",
00018     "activity_type",     "PERIODIC",
00019     "kind",              "VehicleServiceConsumer",
00020     "max_instance",      "1",
00021     "language",          "C++",
00022     "lang_type",         "compile",
00023     // Configuration variables
00024     ""
00025   };
00026 // </rtc-template>
00027 
00028 FmkRobotROSBridge::FmkRobotROSBridge(RTC::Manager* manager)
00029     // <rtc-template block="initializer">
00030   : RTC::DataFlowComponentBase(manager),
00031     m_VehicleServicePort("VehicleService")
00032     // </rtc-template>
00033 {
00034   pos_prev.x = pos_prev.y = pos_prev.theta = 0;
00035 }
00036 
00037 FmkRobotROSBridge::~FmkRobotROSBridge()
00038 {
00039 }
00040 
00041 
00042 RTC::ReturnCode_t FmkRobotROSBridge::onInitialize()
00043 {
00044   // Parameter velocity/acceleration
00045   // ros::param::param<double>("~max_vx", max_vx, 0.3);
00046   // ros::param::param<double>("~max_vw", max_vw, 0.5);
00047   // ros::param::param<double>("~max_ax", max_ax, 0.3);
00048   // ros::param::param<double>("~max_aw", max_aw, 0.5);
00049   ros::param::param<double>("~max_vx", max_vx, 1.0);
00050   ros::param::param<double>("~max_vw", max_vw, 2.0);
00051   ros::param::param<double>("~max_ax", max_ax, 1.0);
00052   ros::param::param<double>("~max_aw", max_aw, 2.0);
00053   // ROS msg/srv port
00054   odometry_pub = nh.advertise<nav_msgs::Odometry>("odom", 1);
00055   velocity_sub = nh.subscribe<geometry_msgs::Twist>("cmd_vel", 1, &FmkRobotROSBridge::onVelocityCommand, this);
00056 
00057   halt_srv = nh.advertiseService("halt_motors",
00058                                  &FmkRobotROSBridge::onHaltMotorService, this);
00059   reset_srv = nh.advertiseService("reset_motors",
00060                                   &FmkRobotROSBridge::onResetMotorService, this);
00061 
00062   // Registration: InPort/OutPort/Service
00063   // <rtc-template block="registration">
00064   // Set InPort buffers
00065 
00066   // Set OutPort buffer
00067 
00068   // Set service provider to Ports
00069 
00070   // Set service consumers to Ports
00071   m_VehicleServicePort.registerConsumer("vehicleService", "VehicleService", m_service0);
00072 
00073   // Set CORBA Service Ports
00074   addPort(m_VehicleServicePort);
00075 
00076   // </rtc-template>
00077 
00078   // <rtc-template block="bind_config">
00079   // Bind variables and configuration variable
00080 
00081   // </rtc-template>
00082 
00083   return RTC::RTC_OK;
00084 }
00085 
00086 
00087 /*
00088 RTC::ReturnCode_t FmkRobotROSBridge::onFinalize()
00089 {
00090   return RTC::RTC_OK;
00091 }
00092 */
00093 /*
00094 RTC::ReturnCode_t FmkRobotROSBridge::onStartup(RTC::UniqueId ec_id)
00095 {
00096   return RTC::RTC_OK;
00097 }
00098 */
00099 /*
00100 RTC::ReturnCode_t FmkRobotROSBridge::onShutdown(RTC::UniqueId ec_id)
00101 {
00102   return RTC::RTC_OK;
00103 }
00104 */
00105 /*
00106 RTC::ReturnCode_t FmkRobotROSBridge::onActivated(RTC::UniqueId ec_id)
00107 {
00108   return RTC::RTC_OK;
00109 }
00110 */
00111 /*
00112 RTC::ReturnCode_t FmkRobotROSBridge::onDeactivated(RTC::UniqueId ec_id)
00113 {
00114   return RTC::RTC_OK;
00115 }
00116 */
00117 
00118 RTC::ReturnCode_t FmkRobotROSBridge::onExecute(RTC::UniqueId ec_id)
00119 {
00120   static ros::Time last_verbose = ros::Time(0);
00121   ros::Duration elapsed = ros::Time::now() - last_verbose;
00122   bool verbose = (elapsed.toSec() > 1.0);
00123   if(verbose) last_verbose = ros::Time::now();
00124 
00125   try {
00126 
00127     if(verbose) {
00128       double voltage;
00129       if( m_service0->getBatteryVoltage(voltage) )
00130         std::cout << "voltage = " << voltage << std::endl;
00131 
00132       char* version = CORBA::string_alloc(1024); // this is for CORBA::String_out
00133       if( m_service0->getIFVersion(version) )
00134         std::cout << "version = " << version << std::endl;
00135       CORBA::string_free(version);
00136 
00137       short val;
00138       char* state = CORBA::string_alloc(1024); // this is for CORBA::String_out
00139       if( m_service0->getState(val,state) )
00140         std::cout << "state = " << state << std::endl;
00141       CORBA::string_free(state);
00142 
00143       short seqsize=16, alarmnum;
00144       SeqAlarm* palarms;
00145       if( m_service0->getActiveAlarm(seqsize, alarmnum, palarms) ) {
00146         for(int cnt=0; cnt < (*palarms).length(); cnt++) {
00147           std::cout << "  alarm[" << cnt+1 << "]:"
00148                     << "code=" << (*palarms)[cnt].code << ", "
00149                     << "type=" << (*palarms)[cnt].type << ", "
00150                     << "src=" << (*palarms)[cnt].source << std::endl;
00151         }
00152       }
00153     }
00154 
00155     Position pos;
00156     static std::vector<double> xhist, zhist;
00157     if( m_service0->getPosition(pos) ) {
00158       if(verbose) {
00159         std::cout << "pos = (" << pos.x  << "[mm],"
00160                   << pos.y << "[mm]," << pos.theta << "[deg])"
00161                   << std::endl;
00162       }
00163       //
00164       nav_msgs::Odometry odom;
00165       odom.header.stamp = ros::Time::now();
00166       odom.header.frame_id = "base_footprint";
00167       odom.pose.pose.position.x = pos.x / 1000.0;
00168       odom.pose.pose.position.y = pos.y / 1000.0;
00169       odom.pose.pose.orientation.w = cos((pos.theta*(M_PI/180.0))/2.0);
00170       odom.pose.pose.orientation.z = sin((pos.theta*(M_PI/180.0))/2.0);
00171 
00172       // for(int i=0;i<36;i++){
00173       //        odom.pose.covariance[i] = 0.01;
00174       //        odom.twist.covariance[i] = 0.01;
00175       // } //for robot_pose_ekf
00176 
00177       double elapsed = (odom.header.stamp.toSec() - tm_prev.toSec());
00178       // pos [mm], linear[m]
00179       // pos [deg], angular[rad]
00180       // std::cerr << "pos.x = " << pos.x ;
00181       // std::cerr << ", pos.x = " << pos.y ;
00182       // std::cerr << ", pos.theta = " << pos.theta ;
00183       // std::cerr << ", pos.x = " << pos.x << " "  << pos_prev.x;
00184       // std::cerr << ", pos.x = " << pos.x << " "  << pos_prev.x;
00185       double x, y, z;
00186       x = (pos.x - pos_prev.x) / 1000.0 / elapsed;
00187       y = (pos.y - pos_prev.y) / 1000.0 / elapsed;
00188       // std::cerr << " : x = " << x;
00189       // std::cerr << " , y = " << y;
00190       //
00191       x = cos(pos_prev.theta*M_PI/180)*x + sin(pos_prev.theta*M_PI/180)*y;
00192       y = sin(pos_prev.theta*M_PI/180)*x - cos(pos_prev.theta*M_PI/180)*y;
00193       z = (pos.theta - pos_prev.theta)*M_PI/180.0 / elapsed;
00194       // average filter
00195       xhist.push_back(x); zhist.push_back(z);
00196       double sum=0;
00197       for(int i=0;i<xhist.size(); i++) x = (sum+=xhist[i])/xhist.size();
00198       sum = 0;
00199       for(int i=0;i<zhist.size(); i++) z = (sum+=zhist[i])/zhist.size();
00200       while(30 < xhist.size()) xhist.erase(xhist.begin());
00201       while(30 < zhist.size()) zhist.erase(zhist.begin());
00202       //
00203       odom.twist.twist.linear.x = x;
00204       odom.twist.twist.linear.y = y;
00205       odom.twist.twist.angular.z = z;
00206       odometry_pub.publish(odom);
00207       pos_prev = pos;
00208       tm_prev = odom.header.stamp;
00209       //
00210       tf::Transform transform;
00211       transform.setOrigin( tf::Vector3(odom.pose.pose.position.x,
00212                                        odom.pose.pose.position.y,
00213                                        0.0) );
00214       transform.setRotation( tf::Quaternion(0, 0,
00215                                             odom.pose.pose.orientation.z,
00216                                             odom.pose.pose.orientation.w) );
00217       tf_pub.sendTransform(tf::StampedTransform(transform, odom.header.stamp, "/odom", "/base_footprint"));
00218     }
00219   }
00220   catch (...) {
00221     std::cout << "No service connected." << std::endl;
00222   }
00223 
00224   //calling all callbacks
00225   while(!ros::getGlobalCallbackQueue()->isEmpty())
00226     ros::spinOnce();
00227 
00228   return RTC::RTC_OK;
00229 }
00230 
00231 /*
00232 RTC::ReturnCode_t FmkRobotROSBridge::onAborting(RTC::UniqueId ec_id)
00233 {
00234   return RTC::RTC_OK;
00235 }
00236 */
00237 /*
00238 RTC::ReturnCode_t FmkRobotROSBridge::onError(RTC::UniqueId ec_id)
00239 {
00240   return RTC::RTC_OK;
00241 }
00242 */
00243 /*
00244 RTC::ReturnCode_t FmkRobotROSBridge::onReset(RTC::UniqueId ec_id)
00245 {
00246   return RTC::RTC_OK;
00247 }
00248 */
00249 /*
00250 RTC::ReturnCode_t FmkRobotROSBridge::onStateUpdate(RTC::UniqueId ec_id)
00251 {
00252   return RTC::RTC_OK;
00253 }
00254 */
00255 /*
00256 RTC::ReturnCode_t FmkRobotROSBridge::onRateChanged(RTC::UniqueId ec_id)
00257 {
00258   return RTC::RTC_OK;
00259 }
00260 */
00261 
00262 void FmkRobotROSBridge::onVelocityCommand(const geometry_msgs::TwistConstPtr& msg) {
00263   //latest_v = ros::Time::now();
00264   velocity = geometry_msgs::Twist(*msg);
00265   //
00266   ros::Time t1 = ros::Time::now();
00267   try {
00268     // limit 0.031 m/sec
00269     //       0.021 rad/s
00270 
00271     m_service0->setJogTimeout(500); // command interval < 100[msec].
00272 
00273     if( !m_service0->moveJog(velocity.linear.x * 1000.0, // m -> mm
00274                              velocity.linear.y * 1000.0, // m -> mm
00275                              velocity.angular.z * 180.0 / M_PI * 13 / 9) ) {
00276       ROS_WARN("commanded velocity is invalid");
00277     }
00278   }
00279   catch (...) {
00280     ROS_ERROR("Error occur in onCommandVelocity");
00281   }
00282   ros::Time t2 = ros::Time::now();
00283   // ROS_WARN_STREAM("fmk-cb " << velocity.linear.x << " "
00284   //              << velocity.linear.y << " "
00285   //              << velocity.angular.z << " "
00286   //              << t2 << " "
00287   //              << t2.toSec() - t1.toSec() );
00288 
00289 }
00290 bool FmkRobotROSBridge::onHaltMotorService(std_srvs::Empty::Request  &req,
00291                                            std_srvs::Empty::Response &res) {
00292   m_service0->stop();
00293   m_service0->setServo(false);
00294   m_service0->setPower(false);
00295 
00296   return true;
00297 }
00298 
00299 bool FmkRobotROSBridge::onResetMotorService(std_srvs::Empty::Request  &req,
00300                                             std_srvs::Empty::Response &res) {
00301 
00302   // check velocity/acceleration
00303   Velocity vel;
00304   Acc acc;
00305   m_service0->getVelocityLimit(vel.translation, vel.rotation);
00306   m_service0->getAccelerationLimit(acc.translation, acc.rotation);
00307   ROS_WARN("Velocity Limit : translation=%lf, rotation=%lf",vel.translation,vel.rotation);
00308   ROS_WARN("Acceleration Limit : translation=%lf, rotation=%lf",acc.translation,acc.rotation);
00309 
00310   vel.translation = std::min(vel.translation, max_vx * 1000);
00311   vel.rotation    = std::min(vel.rotation,    max_vw * 180.0 / M_PI);
00312   m_service0->setVelocity(vel);
00313 
00314   acc.translation = std::min(acc.translation, max_ax * 1000);
00315   acc.rotation    = std::min(acc.rotation,    max_aw * 180.0 / M_PI);
00316   m_service0->setAcceleration(acc);
00317 
00318   ROS_WARN("Set Velocity Limit : translation=%lf, rotation=%lf",vel.translation,vel.rotation);
00319   ROS_WARN("Set Acceleration Limit : translation=%lf, rotation=%lf",acc.translation,acc.rotation);
00320 
00321   // start
00322   m_service0->clearAlarm();
00323   m_service0->unlock();
00324   m_service0->setPower(true);
00325   m_service0->setServo(true);
00326 
00327   return true;
00328 }
00329 
00330 
00331 
00332 extern "C"
00333 {
00334 
00335   void FmkRobotROSBridgeInit(RTC::Manager* manager)
00336   {
00337     coil::Properties profile(fmkrobotrosbridge_spec);
00338     manager->registerFactory(profile,
00339                              RTC::Create<FmkRobotROSBridge>,
00340                              RTC::Delete<FmkRobotROSBridge>);
00341   }
00342 
00343 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


fmk_ros_bridge
Author(s): Manabu Saito, Haseru Azuma
autogenerated on Thu Jun 27 2013 14:58:31