00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00055
00056
00057
00058
00059 #include <ros/ros.h>
00060 #include <urdf/model.h>
00061 #include <actionlib/server/simple_action_server.h>
00062
00063
00064 #include <sensor_msgs/JointState.h>
00065
00066 #include <control_msgs/FollowJointTrajectoryAction.h>
00067 #include <pr2_controllers_msgs/JointTrajectoryControllerState.h>
00068 #include <diagnostic_msgs/DiagnosticArray.h>
00069
00070
00071 #include <cob_srvs/Trigger.h>
00072 #include <cob_srvs/SetOperationMode.h>
00073 #include <cob_srvs/SetDefaultVel.h>
00074
00075
00076 #include <cob_camera_axis/ElmoCtrl.h>
00077
00078 #include <unistd.h>
00079
00080
00081
00082 class NodeClass
00083 {
00084
00085 public:
00086
00087 ros::NodeHandle n_;
00088
00089
00090 ros::Publisher topicPub_JointState_;
00091 ros::Publisher topicPub_ControllerState_;
00092 ros::Publisher topicPub_Diagnostic_;
00093
00094
00095 ros::Subscriber topicSub_JointCommand_;
00096
00097
00098 ros::ServiceServer srvServer_Init_;
00099 ros::ServiceServer srvServer_Stop_;
00100 ros::ServiceServer srvServer_Recover_;
00101 ros::ServiceServer srvServer_SetOperationMode_;
00102 ros::ServiceServer srvServer_SetDefaultVel_;
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> as_;
00113 std::string action_name_;
00114 control_msgs::FollowJointTrajectoryFeedback feedback_;
00115 control_msgs::FollowJointTrajectoryResult result_;
00116
00117
00118 ElmoCtrl * CamAxis_;
00119 ElmoCtrlParams* CamAxisParams_;
00120
00121 std::string CanDevice_;
00122 std::string CanIniFile_;
00123 int CanBaudrate_;
00124 int HomingDir_;
00125 int HomingDigIn_;
00126 double MaxVel_;
00127 int ModID_;
00128 std::string operationMode_;
00129 double LowerLimit_;
00130 double UpperLimit_;
00131 double Offset_;
00132 int MotorDirection_;
00133 int EnoderIncrementsPerRevMot_;
00134 double GearRatio_;
00135
00136 std::string JointName_;
00137 bool isInitialized_;
00138 bool isError_;
00139 bool finished_;
00140 double ActualPos_;
00141 double ActualVel_;
00142 double GoalPos_;
00143 trajectory_msgs::JointTrajectory traj_;
00144 trajectory_msgs::JointTrajectoryPoint traj_point_;
00145 unsigned int traj_point_nr_;
00146
00147
00148 NodeClass(std::string name):
00149 as_(n_, name, boost::bind(&NodeClass::executeCB, this, _1)),
00150 action_name_(name)
00151 {
00152 n_ = ros::NodeHandle("~");
00153
00154 isInitialized_ = false;
00155 isError_ = false;
00156 ActualPos_=0.0;
00157 ActualVel_=0.0;
00158
00159 CamAxis_ = new ElmoCtrl();
00160 CamAxisParams_ = new ElmoCtrlParams();
00161
00162
00163 topicPub_JointState_ = n_.advertise<sensor_msgs::JointState>("/joint_states", 1);
00164 topicPub_ControllerState_ = n_.advertise<pr2_controllers_msgs::JointTrajectoryControllerState>("state", 1);
00165 topicPub_Diagnostic_ = n_.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1);
00166
00167
00168
00169
00170
00171 srvServer_Init_ = n_.advertiseService("init", &NodeClass::srvCallback_Init, this);
00172 srvServer_Stop_ = n_.advertiseService("stop", &NodeClass::srvCallback_Stop, this);
00173 srvServer_Recover_ = n_.advertiseService("recover", &NodeClass::srvCallback_Recover, this);
00174 srvServer_SetOperationMode_ = n_.advertiseService("set_operation_mode", &NodeClass::srvCallback_SetOperationMode, this);
00175 srvServer_SetDefaultVel_ = n_.advertiseService("set_default_vel", &NodeClass::srvCallback_SetDefaultVel, this);
00176
00177
00178
00179
00180
00181 if(!n_.hasParam("EnoderIncrementsPerRevMot")) ROS_WARN("cob_head_axis: couldn't find parameter EnoderIncrementsPerRevMot, check if ALL parameters have been set correctly");
00182
00183 n_.param<std::string>("CanDevice", CanDevice_, "PCAN");
00184 n_.param<int>("CanBaudrate", CanBaudrate_, 500);
00185 n_.param<int>("HomingDir", HomingDir_, 1);
00186 n_.param<int>("HomingDigIn", HomingDigIn_, 11);
00187 n_.param<int>("ModId",ModID_, 17);
00188 n_.param<std::string>("JointName",JointName_, "head_axis_joint");
00189 n_.param<std::string>("CanIniFile",CanIniFile_, "/");
00190 n_.param<std::string>("operation_mode",operationMode_, "position");
00191 n_.param<int>("MotorDirection",MotorDirection_, 1);
00192 n_.param<double>("GearRatio",GearRatio_, 62.5);
00193 n_.param<int>("EnoderIncrementsPerRevMot",EnoderIncrementsPerRevMot_, 4096);
00194
00195 ROS_INFO("CanDevice=%s, CanBaudrate=%d, ModID=%d, HomingDigIn=%d",CanDevice_.c_str(),CanBaudrate_,ModID_,HomingDigIn_);
00196
00197
00198
00199 std::string param_name = "/robot_description";
00200 std::string full_param_name;
00201 std::string xml_string;
00202 n_.searchParam(param_name,full_param_name);
00203 n_.getParam(full_param_name.c_str(),xml_string);
00204 ROS_INFO("full_param_name=%s",full_param_name.c_str());
00205 if (xml_string.size()==0)
00206 {
00207 ROS_ERROR("Unable to load robot model from param server robot_description\n");
00208 exit(2);
00209 }
00210 ROS_DEBUG("%s content\n%s", full_param_name.c_str(), xml_string.c_str());
00211
00212
00213 urdf::Model model;
00214 if (!model.initString(xml_string))
00215 {
00216 ROS_ERROR("Failed to parse urdf file");
00217 exit(2);
00218 }
00219 ROS_INFO("Successfully parsed urdf file");
00220
00221
00222 LowerLimit_ = model.getJoint(JointName_.c_str())->limits->lower;
00223
00224 CamAxisParams_->SetLowerLimit(LowerLimit_);
00225
00226
00227 UpperLimit_ = model.getJoint(JointName_.c_str())->limits->upper;
00228
00229 CamAxisParams_->SetUpperLimit(UpperLimit_);
00230
00231
00232 Offset_ = model.getJoint(JointName_.c_str())->calibration->rising.get()[0];
00233
00234 CamAxisParams_->SetAngleOffset(Offset_);
00235
00236
00237 MaxVel_ = model.getJoint(JointName_.c_str())->limits->velocity;
00238 ROS_INFO("Successfully read limits from urdf");
00239
00240
00241
00242 CamAxisParams_->SetCanIniFile(CanIniFile_);
00243 CamAxisParams_->SetHomingDir(HomingDir_);
00244 CamAxisParams_->SetHomingDigIn(HomingDigIn_);
00245 CamAxisParams_->SetMaxVel(MaxVel_);
00246 CamAxisParams_->SetGearRatio(GearRatio_);
00247 CamAxisParams_->SetMotorDirection(MotorDirection_);
00248 CamAxisParams_->SetEncoderIncrements(EnoderIncrementsPerRevMot_);
00249
00250
00251
00252
00253 CamAxisParams_->Init(CanDevice_, CanBaudrate_, ModID_);
00254
00255
00256 }
00257
00258
00259 ~NodeClass()
00260 {
00261 delete CamAxis_;
00262 }
00263
00264
00265 void executeCB(const control_msgs::FollowJointTrajectoryGoalConstPtr &goal) {
00266 if(isInitialized_) {
00267 ROS_INFO("Received new goal trajectory with %d points",goal->trajectory.points.size());
00268
00269 traj_ = goal->trajectory;
00270 traj_point_nr_ = 0;
00271 traj_point_ = traj_.points[traj_point_nr_];
00272 GoalPos_ = traj_point_.positions[0];
00273 finished_ = false;
00274
00275
00276 CamAxis_->Stop();
00277
00278
00279 if (as_.isPreemptRequested())
00280 {
00281 ROS_INFO("%s: Preempted", action_name_.c_str());
00282
00283 as_.setPreempted();
00284 }
00285
00286 usleep(2000000);
00287
00288 while (not finished_)
00289 {
00290 if (as_.isNewGoalAvailable())
00291 {
00292 ROS_WARN("%s: Aborted", action_name_.c_str());
00293 as_.setAborted();
00294 return;
00295 }
00296 usleep(10000);
00297
00298
00299 }
00300
00301
00302
00303 ROS_INFO("%s: Succeeded", action_name_.c_str());
00304
00305 as_.setSucceeded(result_);
00306
00307 } else {
00308 as_.setAborted();
00309 ROS_WARN("Camera_axis not initialized yet!");
00310 }
00311 }
00312
00313
00314
00315 bool srvCallback_Init(cob_srvs::Trigger::Request &req,
00316 cob_srvs::Trigger::Response &res )
00317 {
00318 if (isInitialized_ == false) {
00319 ROS_INFO("...initializing camera axis...");
00320
00321 if (CamAxis_->Init(CamAxisParams_))
00322 {
00323 CamAxis_->setGearPosVelRadS(0.0f, MaxVel_);
00324 ROS_INFO("Initializing of camera axis successfully");
00325 isInitialized_ = true;
00326 res.success.data = true;
00327 res.error_message.data = "initializing camera axis successfully";
00328 }
00329 else
00330 {
00331 ROS_ERROR("Initializing camera axis not successfully \n");
00332 res.success.data = false;
00333 res.error_message.data = "initializing camera axis not successfully";
00334 }
00335 }
00336 else
00337 {
00338 ROS_WARN("...camera axis already initialized...");
00339 res.success.data = true;
00340 res.error_message.data = "camera axis already initialized";
00341 }
00342
00343 return true;
00344 }
00345
00346 bool srvCallback_Stop(cob_srvs::Trigger::Request &req,
00347 cob_srvs::Trigger::Response &res )
00348 {
00349 ROS_INFO("Stopping camera axis");
00350 if(isInitialized_)
00351 {
00352
00353 if (CamAxis_->Stop()) {
00354 ROS_INFO("Stopping camera axis successfully");
00355 res.success.data = true;
00356 res.error_message.data = "camera axis stopped successfully";
00357 }
00358 else {
00359 ROS_ERROR("Stopping camera axis not successfully. error");
00360 res.success.data = false;
00361 res.error_message.data = "stopping camera axis not successfully";
00362 }
00363 }
00364 return true;
00365 }
00366
00367 bool srvCallback_Recover(cob_srvs::Trigger::Request &req,
00368 cob_srvs::Trigger::Response &res )
00369 {
00370 if (isInitialized_) {
00371 ROS_INFO("Recovering camera axis");
00372
00373
00374 if (CamAxis_->RecoverAfterEmergencyStop()) {
00375 ROS_INFO("Recovering camera axis successfully");
00376 res.success.data = true;
00377 res.error_message.data = "camera axis successfully recovered";
00378 } else {
00379 ROS_ERROR("Recovering camera axis not successfully. error");
00380 res.success.data = false;
00381 res.error_message.data = "recovering camera axis failed";
00382 }
00383 } else {
00384 ROS_WARN("...camera axis already recovered...");
00385 res.success.data = true;
00386 res.error_message.data = "camera axis already recovered";
00387 }
00388
00389 return true;
00390 }
00391
00399 bool srvCallback_SetOperationMode( cob_srvs::SetOperationMode::Request &req,
00400 cob_srvs::SetOperationMode::Response &res )
00401 {
00402 ROS_INFO("Set operation mode to [%s]", req.operation_mode.data.c_str());
00403 n_.setParam("operation_mode", req.operation_mode.data.c_str());
00404 res.success.data = true;
00405 return true;
00406 }
00407
00415 bool srvCallback_SetDefaultVel( cob_srvs::SetDefaultVel::Request &req,
00416 cob_srvs::SetDefaultVel::Response &res )
00417 {
00418 ROS_INFO("Set default velocity to [%f]", req.default_vel);
00419 MaxVel_ = req.default_vel;
00420 CamAxisParams_->SetMaxVel(MaxVel_);
00421 CamAxis_->setMaxVelocity(MaxVel_);
00422 res.success.data = true;
00423 return true;
00424 }
00425
00426
00427 void updateCommands()
00428 {
00429 if (isInitialized_ == true)
00430 {
00431 if (operationMode_ == "position")
00432 {
00433 ROS_DEBUG("moving head_axis in position mode");
00434
00435 if (fabs(ActualVel_) < 0.02)
00436 {
00437
00438
00439 ROS_DEBUG("next point is %d from %d",traj_point_nr_,traj_.points.size());
00440
00441 if (traj_point_nr_ < traj_.points.size())
00442 {
00443
00444 ROS_INFO("...moving to trajectory point[%d], %f",traj_point_nr_,traj_.points[traj_point_nr_].positions[0]);
00445 traj_point_ = traj_.points[traj_point_nr_];
00446 CamAxis_->setGearPosVelRadS(traj_point_.positions[0], MaxVel_);
00447 usleep(900000);
00448 CamAxis_->m_Joint->requestPosVel();
00449 traj_point_nr_++;
00450
00451
00452
00453 }
00454 else if ( fabs( fabs(ActualPos_) - fabs(GoalPos_) ) < 0.5*M_PI/180.0 && !finished_ )
00455 {
00456 ROS_DEBUG("...reached end of trajectory");
00457 finished_ = true;
00458 }
00459 else
00460 {
00461
00462 }
00463 }
00464 else
00465 {
00466 ROS_DEBUG("...axis still moving to point[%d]",traj_point_nr_);
00467 }
00468 }
00469 else if (operationMode_ == "velocity")
00470 {
00471 ROS_WARN("Moving in velocity mode currently disabled");
00472 }
00473 else
00474 {
00475 ROS_ERROR("axis neither in position nor in velocity mode. OperationMode = [%s]", operationMode_.c_str());
00476 }
00477 }
00478 else
00479 {
00480 ROS_DEBUG("axis not initialized");
00481 }
00482 }
00483
00484 void publishJointState()
00485 {
00486
00487 if (isInitialized_ == true) {
00488 isError_ = CamAxis_->isError();
00489
00490
00491 int DOF = 1;
00492
00493 CamAxis_->evalCanBuffer();
00494 CamAxis_->getGearPosVelRadS(&ActualPos_,&ActualVel_);
00495 CamAxis_->m_Joint->requestPosVel();
00496
00497
00498 ActualPos_ = HomingDir_ * ActualPos_;
00499 ActualVel_ = HomingDir_ * ActualVel_;
00500
00501 sensor_msgs::JointState msg;
00502 msg.header.stamp = ros::Time::now();
00503 msg.name.resize(DOF);
00504 msg.position.resize(DOF);
00505 msg.velocity.resize(DOF);
00506 msg.effort.resize(DOF);
00507
00508 msg.name[0] = JointName_;
00509 msg.position[0] = ActualPos_;
00510 msg.velocity[0] = ActualVel_;
00511 msg.effort[0] = 0.0;
00512
00513
00514
00515
00516
00517 topicPub_JointState_.publish(msg);
00518
00519
00520 pr2_controllers_msgs::JointTrajectoryControllerState controllermsg;
00521 controllermsg.header = msg.header;
00522 controllermsg.joint_names.resize(DOF);
00523 controllermsg.desired.positions.resize(DOF);
00524 controllermsg.desired.velocities.resize(DOF);
00525 controllermsg.actual.positions.resize(DOF);
00526 controllermsg.actual.velocities.resize(DOF);
00527 controllermsg.error.positions.resize(DOF);
00528 controllermsg.error.velocities.resize(DOF);
00529
00530 controllermsg.joint_names = msg.name;
00531 controllermsg.desired.positions = msg.position;
00532 controllermsg.desired.velocities = msg.velocity;
00533 controllermsg.actual.positions = msg.position;
00534 controllermsg.actual.velocities = msg.velocity;
00535
00536 for (int i = 0; i<DOF; i++ )
00537 {
00538 controllermsg.error.positions[i] = controllermsg.desired.positions[i] - controllermsg.actual.positions[i];
00539 controllermsg.error.velocities[i] = controllermsg.desired.velocities[i] - controllermsg.actual.velocities[i];
00540 }
00541 topicPub_ControllerState_.publish(controllermsg);
00542 }
00543
00544 diagnostic_msgs::DiagnosticArray diagnostics;
00545 diagnostics.status.resize(1);
00546
00547 if(isError_)
00548 {
00549 diagnostics.status[0].level = 2;
00550 diagnostics.status[0].name = n_.getNamespace();
00551 diagnostics.status[0].message = "drive is in error mode";
00552 }
00553 else
00554 {
00555 if (isInitialized_)
00556 {
00557 diagnostics.status[0].level = 0;
00558 diagnostics.status[0].name = n_.getNamespace();
00559 diagnostics.status[0].message = "head axis initialized and running";
00560 }
00561 else
00562 {
00563 diagnostics.status[0].level = 1;
00564 diagnostics.status[0].name = n_.getNamespace();
00565 diagnostics.status[0].message = "head axis not initialized";
00566 }
00567 }
00568
00569 topicPub_Diagnostic_.publish(diagnostics);
00570 }
00571
00572 };
00573
00574
00575
00576
00577 int main(int argc, char** argv)
00578 {
00579
00580 ros::init(argc, argv, "cob_camera_axis");
00581
00582
00583
00584 NodeClass nodeClass(ros::this_node::getName() + "/follow_joint_trajectory");
00585
00586
00587 ros::Rate loop_rate(10);
00588 while(nodeClass.n_.ok()) {
00589
00590
00591 nodeClass.publishJointState();
00592
00593
00594 nodeClass.updateCommands();
00595
00596
00597 ros::spinOnce();
00598 loop_rate.sleep();
00599 }
00600
00601 return 0;
00602 }
00603