00001
00007 #include "FmkRobotROSBridge.h"
00008
00009
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
00024 ""
00025 };
00026
00027
00028 FmkRobotROSBridge::FmkRobotROSBridge(RTC::Manager* manager)
00029
00030 : RTC::DataFlowComponentBase(manager),
00031 m_VehicleServicePort("VehicleService")
00032
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
00045
00046
00047
00048
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
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
00063
00064
00065
00066
00067
00068
00069
00070
00071 m_VehicleServicePort.registerConsumer("vehicleService", "VehicleService", m_service0);
00072
00073
00074 addPort(m_VehicleServicePort);
00075
00076
00077
00078
00079
00080
00081
00082
00083 return RTC::RTC_OK;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
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);
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);
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
00173
00174
00175
00176
00177 double elapsed = (odom.header.stamp.toSec() - tm_prev.toSec());
00178
00179
00180
00181
00182
00183
00184
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
00189
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
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
00225 while(!ros::getGlobalCallbackQueue()->isEmpty())
00226 ros::spinOnce();
00227
00228 return RTC::RTC_OK;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 void FmkRobotROSBridge::onVelocityCommand(const geometry_msgs::TwistConstPtr& msg) {
00263
00264 velocity = geometry_msgs::Twist(*msg);
00265
00266 ros::Time t1 = ros::Time::now();
00267 try {
00268
00269
00270
00271 m_service0->setJogTimeout(500);
00272
00273 if( !m_service0->moveJog(velocity.linear.x * 1000.0,
00274 velocity.linear.y * 1000.0,
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
00284
00285
00286
00287
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
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
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 };