00001
00062 #include "ros/ros.h"
00063 #include <sensor_msgs/JointState.h>
00064 #include <control_msgs/JointTrajectoryControllerState.h>
00065 #include <actionlib/server/simple_action_server.h>
00066 #include <control_msgs/FollowJointTrajectoryAction.h>
00067
00068 #include <brics_actuator/JointVelocities.h>
00069 #include <cob_trajectory_controller/genericArmCtrl.h>
00070
00071 #include <cob_srvs/Trigger.h>
00072 #include <cob_srvs/SetOperationMode.h>
00073 #include <cob_trajectory_controller/SetFloat.h>
00074
00075
00076 #define HZ 100
00077
00078 class cob_trajectory_controller_node
00079 {
00080 private:
00081 ros::NodeHandle n_;
00082
00083 ros::Publisher joint_vel_pub_;
00084 ros::Subscriber joint_state_sub_;
00085 ros::Subscriber controller_state_;
00086 ros::Subscriber operation_mode_;
00087 ros::ServiceServer srvServer_Stop_;
00088 ros::ServiceServer srvServer_SetVel_;
00089 ros::ServiceServer srvServer_SetAcc_;
00090 ros::ServiceClient srvClient_SetOperationMode;
00091
00092 actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> as_follow_;
00093
00094
00095
00096 std::string action_name_follow_;
00097 std::string current_operation_mode_;
00098 XmlRpc::XmlRpcValue JointNames_param_;
00099 std::vector<std::string> JointNames_;
00100 bool executing_;
00101 bool failure_;
00102 bool rejected_;
00103 bool preemted_;
00104 int DOF;
00105 double velocity_timeout_;
00106
00107 int watchdog_counter;
00108 genericArmCtrl* traj_generator_;
00109 trajectory_msgs::JointTrajectory traj_;
00110 trajectory_msgs::JointTrajectory traj_2_;
00111 std::vector<double> q_current, startposition_, joint_distance_;
00112
00113 public:
00114
00115 cob_trajectory_controller_node():
00116
00117 as_follow_(n_, "follow_joint_trajectory", boost::bind(&cob_trajectory_controller_node::executeFollowTrajectory, this, _1), true),
00118
00119 action_name_follow_("follow_joint_trajectory")
00120 {
00121 joint_vel_pub_ = n_.advertise<brics_actuator::JointVelocities>("command_vel", 1);
00122 joint_state_sub_ = n_.subscribe("/joint_states", 1, &cob_trajectory_controller_node::joint_state_callback, this);
00123 controller_state_ = n_.subscribe("state", 1, &cob_trajectory_controller_node::state_callback, this);
00124 operation_mode_ = n_.subscribe("current_operationmode", 1, &cob_trajectory_controller_node::operationmode_callback, this);
00125 srvServer_Stop_ = n_.advertiseService("stop", &cob_trajectory_controller_node::srvCallback_Stop, this);
00126 srvServer_SetVel_ = n_.advertiseService("set_joint_velocity", &cob_trajectory_controller_node::srvCallback_setVel, this);
00127 srvServer_SetAcc_ = n_.advertiseService("set_joint_acceleration", &cob_trajectory_controller_node::srvCallback_setAcc, this);
00128 srvClient_SetOperationMode = n_.serviceClient<cob_srvs::SetOperationMode>("set_operation_mode");
00129 while(!srvClient_SetOperationMode.exists())
00130 {
00131 ROS_INFO("Waiting for operationmode service to become available");
00132 sleep(1);
00133 }
00134 executing_ = false;
00135 failure_ = false;
00136 rejected_ = false;
00137 preemted_ = false;
00138 watchdog_counter = 0;
00139 current_operation_mode_ = "undefined";
00140 double PTPvel = 0.7;
00141 double PTPacc = 0.2;
00142 double maxError = 0.7;
00143 double overlap_time = 0.4;
00144 velocity_timeout_ = 2.0;
00145 DOF = 7;
00146
00147 ROS_INFO("getting JointNames from parameter server");
00148 if (n_.hasParam("joint_names"))
00149 {
00150 n_.getParam("joint_names", JointNames_param_);
00151 }
00152 else
00153 {
00154 ROS_ERROR("Parameter joint_names not set");
00155 }
00156 JointNames_.resize(JointNames_param_.size());
00157 for (int i = 0; i<JointNames_param_.size(); i++ )
00158 {
00159 JointNames_[i] = (std::string)JointNames_param_[i];
00160 }
00161 DOF = JointNames_param_.size();
00162 if (n_.hasParam("ptp_vel"))
00163 {
00164 n_.getParam("ptp_vel", PTPvel);
00165 }
00166 if (n_.hasParam("ptp_acc"))
00167 {
00168 n_.getParam("ptp_acc", PTPacc);
00169 }
00170 if (n_.hasParam("max_error"))
00171 {
00172 n_.getParam("max_error", maxError);
00173 }
00174 if (n_.hasParam("overlap_time"))
00175 {
00176 n_.getParam("overlap_time", overlap_time);
00177 }
00178 q_current.resize(DOF);
00179 ROS_INFO("starting controller with DOF: %d PTPvel: %f PTPAcc: %f maxError %f", DOF, PTPvel, PTPacc, maxError);
00180 traj_generator_ = new genericArmCtrl(DOF, PTPvel, PTPacc, maxError);
00181 traj_generator_->overlap_time = overlap_time;
00182 }
00183
00184 double getFrequency()
00185 {
00186 double frequency;
00187 if (n_.hasParam("frequency"))
00188 {
00189 n_.getParam("frequency", frequency);
00190 ROS_INFO("Setting controller frequency to %f HZ", frequency);
00191 }
00192 else
00193 {
00194 frequency = 100;
00195 ROS_WARN("Parameter frequency not available, setting to default value: %f Hz", frequency);
00196 }
00197 return frequency;
00198 }
00199
00200 bool srvCallback_Stop(cob_srvs::Trigger::Request &req, cob_srvs::Trigger::Response &res)
00201 {
00202 ROS_INFO("Stopping trajectory controller.");
00203
00204
00205 executing_ = false;
00206 res.success.data = true;
00207 traj_generator_->isMoving = false;
00208
00209 failure_ = true;
00210 return true;
00211 }
00212
00213 bool srvCallback_setVel(cob_trajectory_controller::SetFloat::Request &req, cob_trajectory_controller::SetFloat::Response &res)
00214 {
00215 ROS_INFO("Setting velocity to %f", req.value.data);
00216 traj_generator_->SetPTPvel(req.value.data);
00217 res.success.data = true;
00218 return true;
00219 }
00220
00221 bool srvCallback_setAcc(cob_trajectory_controller::SetFloat::Request &req, cob_trajectory_controller::SetFloat::Response &res)
00222 {
00223 ROS_INFO("Setting acceleration to %f", req.value.data);
00224 traj_generator_->SetPTPacc(req.value.data);
00225 res.success.data = true;
00226 return true;
00227 }
00228
00229 void operationmode_callback(const std_msgs::StringPtr& message)
00230 {
00231 ROS_INFO("Setting operation_mode: %s", (message->data).c_str());
00232 current_operation_mode_ = message->data;
00233 }
00234
00235 void state_callback(const control_msgs::JointTrajectoryControllerStatePtr& message)
00236 {
00237 std::vector<double> positions = message->actual.positions;
00238 for(unsigned int i = 0; i < positions.size(); i++)
00239 {
00240 q_current[i] = positions[i];
00241 }
00242 }
00243
00244 void joint_state_callback(const sensor_msgs::JointStatePtr& message)
00245 {
00246 for(unsigned int i = 0; i < message->name.size(); i++)
00247 {
00248 for(unsigned int j = 0; j < DOF; j++)
00249 {
00250 if(message->name[i]==JointNames_[j])
00251 q_current[j] = message->position[i];
00252 }
00253 }
00254 }
00255
00256 void spawnTrajector(trajectory_msgs::JointTrajectory trajectory)
00257 {
00258 if(!executing_ || preemted_)
00259 {
00260
00261 cob_srvs::SetOperationMode opmode;
00262 opmode.request.operation_mode.data = "velocity";
00263 srvClient_SetOperationMode.call(opmode);
00264 ros::Time begin = ros::Time::now();
00265 while(current_operation_mode_ != "velocity")
00266 {
00267 ROS_INFO("waiting for component to go to velocity mode");
00268 usleep(100000);
00269
00270 if((ros::Time::now() - begin).toSec() > velocity_timeout_)
00271 {
00272 rejected_ = true;
00273 return;
00274 }
00275 }
00276
00277 std::vector<double> traj_start;
00278 if(preemted_ == true)
00279 {
00280 ROS_INFO("There is a old trajectory currently running");
00281 traj_start = traj_generator_->last_q;
00282 trajectory_msgs::JointTrajectory temp_traj;
00283 temp_traj = trajectory;
00284
00285 trajectory_msgs::JointTrajectoryPoint p;
00286 p.positions.resize(DOF);
00287 p.velocities.resize(DOF);
00288 p.accelerations.resize(DOF);
00289 for(int i = 0; i<DOF; i++)
00290 {
00291 p.positions.at(i) = traj_start.at(i);
00292 p.velocities.at(i) = 0.0;
00293 p.accelerations.at(i) = 0.0;
00294 }
00295 std::vector<trajectory_msgs::JointTrajectoryPoint>::iterator it;
00296 it = temp_traj.points.begin();
00297 temp_traj.points.insert(it,p);
00298
00299 for(int i = 0; i<DOF; i++)
00300 {
00301 p.positions.at(i) = traj_generator_->last_q1.at(i);
00302 p.velocities.at(i) = 0.0;
00303 p.accelerations.at(i) = 0.0;
00304 }
00305 it = temp_traj.points.begin();
00306 temp_traj.points.insert(it,p);
00307 for(int i = 0; i<DOF; i++)
00308 {
00309 p.positions.at(i) = traj_generator_->last_q2.at(i);
00310 p.velocities.at(i) = 0.0;
00311 p.accelerations.at(i) = 0.0;
00312 }
00313 it = temp_traj.points.begin();
00314 temp_traj.points.insert(it,p);
00315 for(int i = 0; i<DOF; i++)
00316 {
00317 p.positions.at(i) = traj_generator_->last_q3.at(i);
00318 p.velocities.at(i) = 0.0;
00319 p.accelerations.at(i) = 0.0;
00320 }
00321 it = temp_traj.points.begin();
00322 temp_traj.points.insert(it,p);
00323 for(int i = 0; i<DOF; i++)
00324 {
00325 p.positions.at(i) = q_current.at(i);
00326 p.velocities.at(i) = 0.0;
00327 p.accelerations.at(i) = 0.0;
00328 }
00329 it = temp_traj.points.begin();
00330 temp_traj.points.insert(it,p);
00331 traj_generator_->isMoving = false ;
00332 traj_generator_->moveTrajectory(temp_traj, traj_start);
00333 }
00334 else
00335 {
00336 traj_start = q_current;
00337 trajectory_msgs::JointTrajectory temp_traj;
00338 temp_traj = trajectory;
00339 if(temp_traj.points.size() == 1)
00340 {
00341 traj_generator_->isMoving = false ;
00342 traj_generator_->moveThetas(temp_traj.points[0].positions, traj_start);
00343 }
00344 else
00345 {
00346
00347 trajectory_msgs::JointTrajectoryPoint p;
00348 p.positions.resize(DOF);
00349 p.velocities.resize(DOF);
00350 p.accelerations.resize(DOF);
00351 for(int i = 0; i<DOF; i++)
00352 {
00353 p.positions.at(i) = traj_start.at(i);
00354 p.velocities.at(i) = 0.0;
00355 p.accelerations.at(i) = 0.0;
00356 }
00357 std::vector<trajectory_msgs::JointTrajectoryPoint>::iterator it;
00358 it = temp_traj.points.begin();
00359 temp_traj.points.insert(it,p);
00360 traj_generator_->isMoving = false ;
00361 traj_generator_->moveTrajectory(temp_traj, traj_start);
00362 }
00363 }
00364
00365 executing_ = true;
00366 startposition_ = q_current;
00367 preemted_ = false;
00368
00369 }
00370 else
00371 {
00372 }
00373 while(executing_)
00374 {
00375 if(!preemted_)
00376 {
00377 usleep(1000);
00378 }
00379 else
00380 {
00381 return;
00382 }
00383 }
00384 }
00385
00386
00387 void executeFollowTrajectory(const control_msgs::FollowJointTrajectoryGoalConstPtr &goal)
00388 {
00389 ROS_INFO("Received new goal trajectory with %lu points",goal->trajectory.points.size());
00390 spawnTrajector(goal->trajectory);
00391
00392 if(rejected_)
00393 as_follow_.setAborted();
00394 else
00395 {
00396 if(failure_)
00397 as_follow_.setAborted();
00398 else
00399 as_follow_.setSucceeded();
00400 }
00401 rejected_ = false;
00402 failure_ = false;
00403 }
00404
00405 void run()
00406 {
00407 if(executing_)
00408 {
00409 failure_ = false;
00410 watchdog_counter = 0;
00411
00412 if (!ros::ok() || current_operation_mode_ != "velocity")
00413 {
00414
00415 executing_ = false;
00416 traj_generator_->isMoving = false;
00417
00418 failure_ = true;
00419 return;
00420 }
00421 if (as_follow_.isPreemptRequested())
00422 {
00423
00424 failure_ = true;
00425 preemted_ = true;
00426 ROS_INFO("Preempted trajectory action");
00427 return;
00428 }
00429 std::vector<double> des_vel;
00430 if(traj_generator_->step(q_current, des_vel))
00431 {
00432 if(!traj_generator_->isMoving)
00433 {
00434 executing_ = false;
00435 preemted_ = false;
00436 }
00437 brics_actuator::JointVelocities target_joint_vel;
00438 target_joint_vel.velocities.resize(DOF);
00439 for(int i=0; i<DOF; i++)
00440 {
00441 target_joint_vel.velocities[i].joint_uri = JointNames_[i].c_str();
00442 target_joint_vel.velocities[i].unit = "rad";
00443 target_joint_vel.velocities[i].value = des_vel.at(i);
00444 }
00445
00446
00447 joint_vel_pub_.publish(target_joint_vel);
00448 }
00449 else
00450 {
00451 ROS_INFO("An controller error occured!");
00452 failure_ = true;
00453 executing_ = false;
00454 }
00455 }
00456 else
00457 {
00458 if(watchdog_counter < 10)
00459 {
00460 brics_actuator::JointVelocities target_joint_vel;
00461 target_joint_vel.velocities.resize(DOF);
00462 for (int i = 0; i < DOF; i += 1)
00463 {
00464 target_joint_vel.velocities[i].joint_uri = JointNames_[i].c_str();
00465 target_joint_vel.velocities[i].unit = "rad";
00466 target_joint_vel.velocities[i].value = 0;
00467 }
00468 joint_vel_pub_.publish(target_joint_vel);
00469 ROS_INFO("Publishing 0-vel (%d)", DOF);
00470 }
00471 watchdog_counter++;
00472 }
00473 }
00474
00475 };
00476
00477
00478
00479 int main(int argc, char ** argv)
00480 {
00481 ros::init(argc, argv, "cob_trajectory_controller");
00482
00483 cob_trajectory_controller_node tm;
00484
00486 double frequency = tm.getFrequency();
00487
00488 ros::Rate loop_rate(frequency);
00489 while (ros::ok())
00490 {
00491 tm.run();
00492 ros::spinOnce();
00493 loop_rate.sleep();
00494 }
00495 }
00496
00497
00498
00499