00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "ros/ros.h"
00019 #include <std_msgs/String.h>
00020 #include <std_msgs/Float64MultiArray.h>
00021 #include <sensor_msgs/JointState.h>
00022 #include <control_msgs/JointTrajectoryControllerState.h>
00023 #include <actionlib/server/simple_action_server.h>
00024 #include <control_msgs/FollowJointTrajectoryAction.h>
00025
00026 #include <cob_trajectory_controller/genericArmCtrl.h>
00027
00028 #include <std_srvs/Trigger.h>
00029 #include <cob_srvs/SetString.h>
00030 #include <cob_srvs/SetFloat.h>
00031
00032
00033 #define HZ 100
00034
00035 class cob_trajectory_controller_node
00036 {
00037 private:
00038 ros::NodeHandle n_;
00039 ros::NodeHandle n_private_;
00040
00041 ros::Publisher joint_vel_pub_;
00042 ros::Subscriber controller_state_;
00043 ros::Subscriber operation_mode_;
00044 ros::ServiceServer srvServer_Stop_;
00045 ros::ServiceServer srvServer_SetVel_;
00046 ros::ServiceServer srvServer_SetAcc_;
00047 ros::ServiceClient srvClient_SetOperationMode;
00048
00049 actionlib::SimpleActionServer<control_msgs::FollowJointTrajectoryAction> as_;
00050
00051 std::string action_name_;
00052 std::string current_operation_mode_;
00053 std::vector<std::string> JointNames_;
00054 bool executing_;
00055 bool failure_;
00056 bool rejected_;
00057 bool preemted_;
00058 int DOF;
00059 double velocity_timeout_;
00060
00061 int watchdog_counter;
00062 genericArmCtrl* traj_generator_;
00063 trajectory_msgs::JointTrajectory traj_;
00064 trajectory_msgs::JointTrajectory traj_2_;
00065 std::vector<double> q_current, startposition_, joint_distance_;
00066
00067 public:
00068
00069 cob_trajectory_controller_node():
00070 as_(n_, "joint_trajectory_controller/follow_joint_trajectory", boost::bind(&cob_trajectory_controller_node::executeFollowTrajectory, this, _1), false),
00071 action_name_("follow_joint_trajectory")
00072 {
00073 joint_vel_pub_ = n_.advertise<std_msgs::Float64MultiArray>("joint_group_velocity_controller/command", 1);
00074 controller_state_ = n_.subscribe("joint_trajectory_controller/state", 1, &cob_trajectory_controller_node::state_callback, this);
00075 operation_mode_ = n_.subscribe("driver/current_operationmode", 1, &cob_trajectory_controller_node::operationmode_callback, this);
00076 srvServer_Stop_ = n_.advertiseService("driver/stop", &cob_trajectory_controller_node::srvCallback_Stop, this);
00077 srvServer_SetVel_ = n_.advertiseService("driver/set_joint_velocity", &cob_trajectory_controller_node::srvCallback_setVel, this);
00078 srvServer_SetAcc_ = n_.advertiseService("driver/set_joint_acceleration", &cob_trajectory_controller_node::srvCallback_setAcc, this);
00079 srvClient_SetOperationMode = n_.serviceClient<cob_srvs::SetString>("driver/set_operation_mode");
00080 while(!srvClient_SetOperationMode.exists())
00081 {
00082 ROS_INFO("Waiting for operationmode service to become available");
00083 sleep(1);
00084 }
00085 executing_ = false;
00086 failure_ = false;
00087 rejected_ = false;
00088 preemted_ = false;
00089 watchdog_counter = 0;
00090 current_operation_mode_ = "undefined";
00091 double PTPvel = 0.7;
00092 double PTPacc = 0.2;
00093 double maxError = 0.7;
00094 double overlap_time = 0.4;
00095 velocity_timeout_ = 2.0;
00096 DOF = 7;
00097
00098 ROS_INFO("getting JointNames from parameter server: %s", n_private_.getNamespace().c_str());
00099 if (n_private_.hasParam("joint_names"))
00100 {
00101 n_private_.getParam("joint_names", JointNames_);
00102 }
00103 else
00104 {
00105 ROS_ERROR("Parameter 'joint_names' not set");
00106 }
00107 DOF = JointNames_.size();
00108
00109 if (n_private_.hasParam("ptp_vel"))
00110 {
00111 n_private_.getParam("ptp_vel", PTPvel);
00112 }
00113 if (n_private_.hasParam("ptp_acc"))
00114 {
00115 n_private_.getParam("ptp_acc", PTPacc);
00116 }
00117 if (n_private_.hasParam("max_error"))
00118 {
00119 n_private_.getParam("max_error", maxError);
00120 }
00121 if (n_private_.hasParam("overlap_time"))
00122 {
00123 n_private_.getParam("overlap_time", overlap_time);
00124 }
00125 if (n_private_.hasParam("operation_mode"))
00126 {
00127 n_private_.getParam("operation_mode", current_operation_mode_);
00128 }
00129 q_current.resize(DOF);
00130 ROS_INFO("starting controller with DOF: %d PTPvel: %f PTPAcc: %f maxError %f", DOF, PTPvel, PTPacc, maxError);
00131 traj_generator_ = new genericArmCtrl(DOF, PTPvel, PTPacc, maxError);
00132 traj_generator_->overlap_time = overlap_time;
00133
00134 as_.start();
00135 }
00136
00137 double getFrequency()
00138 {
00139 double frequency;
00140 if (n_private_.hasParam("frequency"))
00141 {
00142 n_private_.getParam("frequency", frequency);
00143 ROS_INFO("Setting controller frequency to %f HZ", frequency);
00144 }
00145 else
00146 {
00147 frequency = 100;
00148 ROS_WARN("Parameter 'frequency' not available, setting to default value: %f Hz", frequency);
00149 }
00150 return frequency;
00151 }
00152
00153 bool srvCallback_Stop(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
00154 {
00155 ROS_INFO("Stopping trajectory controller.");
00156
00157
00158 executing_ = false;
00159 res.success = true;
00160 traj_generator_->isMoving = false;
00161 failure_ = true;
00162 return true;
00163 }
00164
00165 bool srvCallback_setVel(cob_srvs::SetFloat::Request &req, cob_srvs::SetFloat::Response &res)
00166 {
00167 ROS_INFO("Setting velocity to %f", req.data);
00168 traj_generator_->SetPTPvel(req.data);
00169 res.success = true;
00170 return true;
00171 }
00172
00173 bool srvCallback_setAcc(cob_srvs::SetFloat::Request &req, cob_srvs::SetFloat::Response &res)
00174 {
00175 ROS_INFO("Setting acceleration to %f", req.data);
00176 traj_generator_->SetPTPacc(req.data);
00177 res.success = true;
00178 return true;
00179 }
00180
00181 void operationmode_callback(const std_msgs::StringPtr& message)
00182 {
00183 current_operation_mode_ = message->data;
00184 }
00185
00186 void state_callback(const control_msgs::JointTrajectoryControllerStatePtr& message)
00187 {
00188 std::vector<double> positions = message->actual.positions;
00189 for(unsigned int i = 0; i < positions.size(); i++)
00190 {
00191 q_current[i] = positions[i];
00192 }
00193 }
00194
00195 void spawnTrajector(trajectory_msgs::JointTrajectory trajectory)
00196 {
00197 if(!executing_ || preemted_)
00198 {
00199
00200 cob_srvs::SetString opmode;
00201 opmode.request.data = "velocity";
00202 srvClient_SetOperationMode.call(opmode);
00203 ros::Time begin = ros::Time::now();
00204 while(current_operation_mode_ != "velocity")
00205 {
00206 ROS_INFO("waiting for component to go to velocity mode");
00207 usleep(100000);
00208
00209 if((ros::Time::now() - begin).toSec() > velocity_timeout_)
00210 {
00211 rejected_ = true;
00212 return;
00213 }
00214 }
00215
00216 std::vector<double> traj_start;
00217 if(preemted_ == true)
00218 {
00219 ROS_INFO("There is a old trajectory currently running");
00220 traj_start = traj_generator_->last_q;
00221 trajectory_msgs::JointTrajectory temp_traj;
00222 temp_traj = trajectory;
00223
00224 trajectory_msgs::JointTrajectoryPoint p;
00225 p.positions.resize(DOF);
00226 p.velocities.resize(DOF);
00227 p.accelerations.resize(DOF);
00228 for(int i = 0; i<DOF; i++)
00229 {
00230 p.positions.at(i) = traj_start.at(i);
00231 p.velocities.at(i) = 0.0;
00232 p.accelerations.at(i) = 0.0;
00233 }
00234 std::vector<trajectory_msgs::JointTrajectoryPoint>::iterator it;
00235 it = temp_traj.points.begin();
00236 temp_traj.points.insert(it,p);
00237
00238 for(int i = 0; i<DOF; i++)
00239 {
00240 p.positions.at(i) = traj_generator_->last_q1.at(i);
00241 p.velocities.at(i) = 0.0;
00242 p.accelerations.at(i) = 0.0;
00243 }
00244 it = temp_traj.points.begin();
00245 temp_traj.points.insert(it,p);
00246 for(int i = 0; i<DOF; i++)
00247 {
00248 p.positions.at(i) = traj_generator_->last_q2.at(i);
00249 p.velocities.at(i) = 0.0;
00250 p.accelerations.at(i) = 0.0;
00251 }
00252 it = temp_traj.points.begin();
00253 temp_traj.points.insert(it,p);
00254 for(int i = 0; i<DOF; i++)
00255 {
00256 p.positions.at(i) = traj_generator_->last_q3.at(i);
00257 p.velocities.at(i) = 0.0;
00258 p.accelerations.at(i) = 0.0;
00259 }
00260 it = temp_traj.points.begin();
00261 temp_traj.points.insert(it,p);
00262 for(int i = 0; i<DOF; i++)
00263 {
00264 p.positions.at(i) = q_current.at(i);
00265 p.velocities.at(i) = 0.0;
00266 p.accelerations.at(i) = 0.0;
00267 }
00268 it = temp_traj.points.begin();
00269 temp_traj.points.insert(it,p);
00270 traj_generator_->isMoving = false ;
00271 traj_generator_->moveTrajectory(temp_traj, traj_start);
00272 }
00273 else
00274 {
00275 traj_start = q_current;
00276 trajectory_msgs::JointTrajectory temp_traj;
00277 temp_traj = trajectory;
00278 if(temp_traj.points.size() == 1)
00279 {
00280 traj_generator_->isMoving = false ;
00281 traj_generator_->moveThetas(temp_traj.points[0].positions, traj_start);
00282 }
00283 else
00284 {
00285
00286 trajectory_msgs::JointTrajectoryPoint p;
00287 p.positions.resize(DOF);
00288 p.velocities.resize(DOF);
00289 p.accelerations.resize(DOF);
00290 for(int i = 0; i<DOF; i++)
00291 {
00292 p.positions.at(i) = traj_start.at(i);
00293 p.velocities.at(i) = 0.0;
00294 p.accelerations.at(i) = 0.0;
00295 }
00296 std::vector<trajectory_msgs::JointTrajectoryPoint>::iterator it;
00297 it = temp_traj.points.begin();
00298 temp_traj.points.insert(it,p);
00299 traj_generator_->isMoving = false ;
00300 traj_generator_->moveTrajectory(temp_traj, traj_start);
00301 }
00302 }
00303
00304 executing_ = true;
00305 startposition_ = q_current;
00306 preemted_ = false;
00307
00308 }
00309 else
00310 {
00311 }
00312 while(executing_)
00313 {
00314 if(!preemted_)
00315 {
00316 usleep(1000);
00317 }
00318 else
00319 {
00320 return;
00321 }
00322 }
00323 }
00324
00325
00326 void executeFollowTrajectory(const control_msgs::FollowJointTrajectoryGoalConstPtr &goal)
00327 {
00328 ROS_INFO("Received new goal trajectory with %lu points",goal->trajectory.points.size());
00329 spawnTrajector(goal->trajectory);
00330
00331 if(rejected_)
00332 as_.setAborted();
00333 else
00334 {
00335 if(failure_)
00336 as_.setAborted();
00337 else
00338 as_.setSucceeded();
00339 }
00340 rejected_ = false;
00341 failure_ = false;
00342 }
00343
00344 void run()
00345 {
00346 if(executing_)
00347 {
00348 failure_ = false;
00349 watchdog_counter = 0;
00350 if (!ros::ok() || current_operation_mode_ != "velocity")
00351 {
00352
00353 executing_ = false;
00354 traj_generator_->isMoving = false;
00355 failure_ = true;
00356 return;
00357 }
00358 if (as_.isPreemptRequested())
00359 {
00360 failure_ = true;
00361 preemted_ = true;
00362 executing_ = false;
00363 traj_generator_->isMoving = false;
00364 ROS_INFO("Preempted trajectory action");
00365 return;
00366 }
00367 std::vector<double> des_vel;
00368 if(traj_generator_->step(q_current, des_vel))
00369 {
00370 if(!traj_generator_->isMoving)
00371 {
00372 executing_ = false;
00373 preemted_ = false;
00374 }
00375 std_msgs::Float64MultiArray target_joint_vel;
00376 for(int i=0; i<DOF; i++)
00377 {
00378 target_joint_vel.data.push_back(des_vel.at(i));
00379 }
00380
00381
00382 joint_vel_pub_.publish(target_joint_vel);
00383 }
00384 else
00385 {
00386 ROS_INFO("An controller error occured!");
00387 failure_ = true;
00388 executing_ = false;
00389 }
00390 }
00391 else
00392 {
00393 if(watchdog_counter < 10)
00394 {
00395 std_msgs::Float64MultiArray target_joint_vel;
00396 for(int i=0; i<DOF; i++)
00397 {
00398 target_joint_vel.data.push_back(0.0);
00399 }
00400 joint_vel_pub_.publish(target_joint_vel);
00401 }
00402 watchdog_counter++;
00403 }
00404 }
00405
00406 };
00407
00408
00409
00410 int main(int argc, char ** argv)
00411 {
00412 ros::init(argc, argv, "cob_trajectory_controller");
00413
00414 cob_trajectory_controller_node tm;
00415
00417 double frequency = tm.getFrequency();
00418
00419 ros::Rate loop_rate(frequency);
00420 while (ros::ok())
00421 {
00422 tm.run();
00423 ros::spinOnce();
00424 loop_rate.sleep();
00425 }
00426 }
00427
00428
00429