00001 #include "driver/PTUNode.h"
00002
00003
00004 PTUNode::PTUNode(ros::NodeHandle& node_handle):node_handle(node_handle) {
00005 std::string port;
00006 int baud;
00007 bool speed_control;
00008 bool mock_PTU = false;
00009
00010 node_handle.getParam("port", port);
00011 node_handle.getParam("baud", baud);
00012 node_handle.getParam("speed_control", speed_control);
00013 node_handle.getParam("mockPTU", mock_PTU);
00014 ptu = NULL;
00015 if (mock_PTU) {
00016 ptu = new asr_flir_ptu_driver::PTUDriverMock(port.c_str(), baud, speed_control);
00017 }
00018 else {
00019 bool no_device_found = true;
00020 while(no_device_found) {
00021 no_device_found = false;
00022 try {
00023 ptu = new asr_flir_ptu_driver::PTUDriver(port.c_str(), baud, speed_control);
00024 }
00025 catch(std::exception &e) {
00026 ROS_ERROR("NO DEVICE FOUND CONNECTED TO SERIAL PORT %s", port.c_str());
00027 no_device_found = true;
00028 sleep(5);
00029 }
00030 }
00031 }
00032
00033 if (ptu->isConnected()) {
00034 ROS_INFO("PTU is connected");
00035 } else {
00036 ROS_ERROR("Couldn't connect to PTU");
00037 exit(1);
00038 }
00039
00040 setSettings();
00041
00042 ROS_INFO("PTU is fully initialized.");
00043
00044 joint_sub = node_handle.subscribe<asr_flir_ptu_driver::State>(topic_state_command, 1, &PTUNode::setState, this);
00045 joint_pub = node_handle.advertise<asr_flir_ptu_driver::State>(ptu_topic_state, 1);
00046
00047
00048 joint_pub_old = node_handle.advertise<sensor_msgs::JointState>(topic_state, 1);
00049
00050
00051 validate_service = node_handle.advertiseService(service_validation, &PTUNode::validatePanTilt, this);
00052 alive_service = node_handle.advertiseService(service_alive, &PTUNode::emptyAlive, this);
00053 path_prediction_service = node_handle.advertiseService(service_path_prediction, &PTUNode::predict, this);
00054
00055
00056
00057 range_service = node_handle.advertiseService(service_range, &PTUNode::getRange, this);
00058
00059
00060 settings_service = node_handle.advertiseService(service_settings_update, &PTUNode::updateSettings, this);
00061 speedmode_service = node_handle.advertiseService(service_speed_control_update, &PTUNode::updateSpeedControl, this);
00062
00063 }
00064
00065 PTUNode::~PTUNode() {
00066 if (ptu != NULL && ptu->isConnected()) {
00067 ptu->setAbsoluteAngleSpeeds(0.0, 0.0);
00068 }
00069 }
00070
00071
00072 void PTUNode::setState(const asr_flir_ptu_driver::State::ConstPtr& msg) {
00073 ROS_INFO("STATE RECEIVED");
00074 ROS_DEBUG("SETSTATE REQUEST - START");
00075 double pan = msg->state.position[0];
00076 double tilt = msg->state.position[1];
00077 double pan_speed = msg->state.velocity[0];
00078 double tilt_speed = msg->state.velocity[1];
00079 seq_num = msg->seq_num;
00080 ROS_DEBUG_STREAM("Node received state_cmd message: (p,t)=(" << pan << "," << tilt << ") and (v_p,v_t)=(" << pan_speed << "," << tilt_speed << ").");
00081
00082 if (ptu->isInSpeedControlMode()) {
00083 ROS_DEBUG("PTU is in SpeedcontrolMode");
00084 ptu->setAbsoluteAngleSpeeds(pan_speed, tilt_speed);
00085 } else {
00086 ROS_DEBUG("PTU is NOT in SpeedcontrolMode");
00087 ptu->setAbsoluteAngles(pan, tilt, msg->no_check_forbidden_area);
00088
00089 node_handle.setParam("reached_desired_position", false);
00090
00091 }
00092 ROS_DEBUG("SETSTATE REQUEST - END");
00093
00094 }
00095
00096 bool PTUNode::validatePanTilt(asr_flir_ptu_driver::Validate::Request &req, asr_flir_ptu_driver::Validate::Response &res)
00097 {
00098 double pan = req.pan;
00099 double tilt = req.tilt;
00100 double margin = req.margin;
00101
00102 if(ptu->setValuesOutOfLimitsButWithinMarginToLimit(&pan, &tilt, margin)) {
00103 if(ptu->isInForbiddenArea(pan, tilt)) {
00104 res.is_valid = false;
00105 ROS_DEBUG("FORBIDDEN");
00106 }
00107 else {
00108 res.is_valid = true;
00109 ROS_DEBUG("VALID");
00110 }
00111 }
00112 else {
00113 res.is_valid = false;
00114 ROS_DEBUG("OUT OF BOUNDS");
00115 }
00116 res.new_pan = pan;
00117 res.new_tilt = tilt;
00118 return true;
00119 }
00120
00121 bool PTUNode::predict(asr_flir_ptu_driver::Predict::Request &req, asr_flir_ptu_driver::Predict::Response &res) {
00122 std::vector<double> legit_end_point = ptu->determineLegitEndPoint(req.pan, req.tilt);
00123 res.new_pan = legit_end_point[0];
00124 res.new_tilt = legit_end_point[1];
00125 return true;
00126 }
00127
00128
00129 bool PTUNode::emptyAlive(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
00130 {
00131
00132 return true;
00133 }
00134
00135
00136 bool PTUNode::updateSettings(std_srvs::Empty::Request&, std_srvs::Empty::Response&) {
00137 return setSettings();
00138 }
00139
00140 bool PTUNode::getRange(asr_flir_ptu_driver::Range::Request &req, asr_flir_ptu_driver::Range::Response &res)
00141 {
00142 res.pan_min_angle = ptu->getLimitAngle('p', 'l');
00143 res.pan_max_angle = ptu->getLimitAngle('p', 'u');
00144 res.tilt_min_angle = ptu->getLimitAngle('t', 'l');
00145 res.tilt_max_angle = ptu->getLimitAngle('t', 'u');
00146 std::vector<double> forbidden_pan_min, forbidden_pan_max, forbidden_tilt_min, forbidden_tilt_max;
00147 node_handle.getParam("forbidden_pan_min", forbidden_pan_min);
00148 node_handle.getParam("forbidden_pan_max", forbidden_pan_max);
00149 node_handle.getParam("forbidden_tilt_min", forbidden_tilt_min);
00150 node_handle.getParam("forbidden_tilt_max", forbidden_tilt_max);
00151 res.forbidden_pan_min = forbidden_pan_min;
00152 res.forbidden_pan_max = forbidden_pan_max;
00153 res.forbidden_tilt_min = forbidden_tilt_min;
00154 res.forbidden_tilt_max = forbidden_tilt_max;
00155 return true;
00156
00157 }
00158
00159 bool PTUNode::setSettings() {
00160 int pan_base, pan_speed, pan_upper, pan_accel;
00161 int tilt_base, tilt_speed, tilt_upper, tilt_accel;
00162 int pan_hold, pan_move;
00163 int tilt_hold, tilt_move;
00164 double pan_min, pan_max;
00165 double tilt_min, tilt_max;
00166 bool speed_control;
00167
00168 double computation_tolerance;
00169 int distance_factor;
00170
00171
00172
00173 node_handle.getParam("speed_control", speed_control);
00174 node_handle.getParam("pan_min_angle", pan_min);
00175 node_handle.getParam("pan_max_angle", pan_max);
00176 node_handle.getParam("pan_base_speed", pan_base);
00177 node_handle.getParam("pan_target_speed", pan_speed);
00178 node_handle.getParam("pan_upper_speed", pan_upper);
00179 node_handle.getParam("pan_accel", pan_accel);
00180 node_handle.getParam("pan_hold", pan_hold);
00181 node_handle.getParam("pan_move", pan_move);
00182 node_handle.getParam("tilt_min_angle", tilt_min);
00183 node_handle.getParam("tilt_max_angle", tilt_max);
00184 node_handle.getParam("tilt_base_speed", tilt_base);
00185 node_handle.getParam("tilt_target_speed", tilt_speed);
00186 node_handle.getParam("tilt_upper_speed", tilt_upper);
00187 node_handle.getParam("tilt_accel", tilt_accel);
00188 node_handle.getParam("tilt_hold", tilt_hold);
00189 node_handle.getParam("tilt_move", tilt_move);
00190 node_handle.getParam("computation_tolerance", computation_tolerance);
00191 node_handle.getParam("distance_factor", distance_factor);
00192
00193 std::vector<double> forbidden_pan_min;
00194 std::vector<double> forbidden_pan_max;
00195 std::vector<double> forbidden_tilt_min;
00196 std::vector<double> forbidden_tilt_max;
00197 node_handle.getParam("forbidden_pan_min", forbidden_pan_min);
00198 node_handle.getParam("forbidden_pan_max", forbidden_pan_max);
00199 node_handle.getParam("forbidden_tilt_min", forbidden_tilt_min);
00200 node_handle.getParam("forbidden_tilt_max", forbidden_tilt_max);
00201
00202 std::vector< std::map< std::string, double> > forbidden_areas;
00203 for (unsigned int i = 0; i < forbidden_pan_min.size(); i++)
00204 {
00205 std::map< std::string, double> area;
00206 area["pan_min"] = forbidden_pan_min.at(i);
00207 area["pan_max"] = forbidden_pan_max.at(i);
00208 area["tilt_min"] = forbidden_tilt_min.at(i);
00209 area["tilt_max"] = forbidden_tilt_max.at(i);
00210 if (forbidden_pan_min.at(i) < forbidden_pan_max.at(i) &&
00211 forbidden_tilt_min.at(i) < forbidden_tilt_max.at(i))
00212 forbidden_areas.push_back(area);
00213 ROS_DEBUG("forbidden area: %d", i+1);
00214 ROS_DEBUG("forbidden_pan_min:%f, forbidden_pan_min:%f", forbidden_pan_min.at(i), forbidden_pan_max.at(i));
00215 ROS_DEBUG("forbidden_tilt_min:%f, forbidden_tilt_max:%f", forbidden_tilt_min.at(i), forbidden_tilt_max.at(i));
00216
00217 }
00218
00219 ROS_DEBUG("double minPan:%f, double maxPan:%f", pan_min, pan_max);
00220 ROS_DEBUG("double tiltMin:%f, double tiltMax:%f", tilt_min, tilt_max);
00221
00222
00223
00224 ptu->setSettings(pan_base, tilt_base, pan_speed, tilt_speed, pan_upper, tilt_upper, pan_accel,
00225 tilt_accel, pan_hold, tilt_hold, pan_move, tilt_move);
00226 ptu->setForbiddenAreas(forbidden_areas);
00227 ptu->setLimitAngles(pan_min, pan_max, tilt_min, tilt_max);
00228 ptu->setComputationTolerance(computation_tolerance);
00229 ptu->setDistanceFactor(distance_factor);
00230
00231 node_handle.setParam("pan_min_angle", (int) ptu->getLimitAngle('p','l'));
00232 node_handle.setParam("pan_max_angle", (int) ptu->getLimitAngle('p','u'));
00233 node_handle.setParam("pan_base_speed", pan_base);
00234 node_handle.setParam("pan_target_speed", pan_speed);
00235 node_handle.setParam("pan_upper_speed", pan_upper);
00236 node_handle.setParam("pan_accel", pan_accel);
00237 node_handle.setParam("pan_hold", pan_hold);
00238 node_handle.setParam("pan_move", pan_move);
00239 node_handle.setParam("tilt_min_angle", (int) ptu->getLimitAngle('t','l'));
00240 node_handle.setParam("tilt_max_angle", (int) ptu->getLimitAngle('t','u'));
00241 node_handle.setParam("tilt_base_speed", tilt_base);
00242 node_handle.setParam("tilt_target_speed", tilt_speed);
00243 node_handle.setParam("tilt_upper_speed", tilt_upper);
00244 node_handle.setParam("tilt_accel", tilt_accel);
00245 node_handle.setParam("tilt_hold", tilt_hold);
00246 node_handle.setParam("tilt_move", tilt_move);
00247
00248
00249 node_handle.getParam("ptu_pan_frame", ptu_pan_frame);
00250 node_handle.getParam("ptu_pan_frame_rotated", ptu_pan_frame_rotated);
00251 node_handle.getParam("ptu_tilt_frame", ptu_tilt_frame);
00252 node_handle.getParam("ptu_tilt_frame_rotated", ptu_tilt_frame_rotated);
00253
00254
00255 node_handle.getParam("topicStateCommand", topic_state_command);
00256 node_handle.getParam("topicState", topic_state);
00257 node_handle.getParam("ptuTopicState", ptu_topic_state);
00258
00259 ROS_DEBUG("topicStateCommand: %s", topic_state_command.c_str());
00260 ROS_DEBUG("topicState: %s", topic_state.c_str());
00261
00262
00263 node_handle.getParam("serviceSettingsUpdate", service_settings_update);
00264 node_handle.getParam("serviceSpeedControlUpdate", service_speed_control_update);
00265 node_handle.getParam("serviceRange", service_range);
00266 node_handle.getParam("serviceValidation", service_validation);
00267 node_handle.getParam("serviceAlive", service_alive);
00268 node_handle.getParam("servicePathPrediction", service_path_prediction);
00269
00270 ROS_DEBUG("serviceSettingsUpdate: %s", service_settings_update.c_str());
00271 ROS_DEBUG("serviceSpeedControlUpdate: %s", service_speed_control_update.c_str());
00272 ROS_DEBUG("serviceRange: %s", service_range.c_str());
00273
00274
00275 if (node_handle.hasParam("ptu_namespaces"))
00276 {
00277 ROS_INFO("Set namespace");
00278 node_handle.setParam("/ptu_namespaces",node_handle.getNamespace());
00279 }
00280
00281 return true;
00282 }
00283
00284 bool PTUNode::updateSpeedControl(std_srvs::Empty::Request&, std_srvs::Empty::Response&) {
00285 return setSpeedControl();
00286 }
00287
00288 bool PTUNode::setSpeedControl() {
00289 int pan_speed, tilt_speed;
00290 bool speed_control;
00291 node_handle.getParam("speed_control", speed_control);
00292 node_handle.getParam("pan_target_speed", pan_speed);
00293 node_handle.getParam("tilt_target_speed", tilt_speed);
00294
00295
00296
00297
00298 if (ptu->isInSpeedControlMode() & !speed_control) {
00299 ptu->setAbsoluteAngleSpeeds(0.0, 0.0);
00300 ptu->setSpeedControlMode(speed_control);
00301 ptu->setAbsoluteAngleSpeeds((signed short)pan_speed, (signed short)tilt_speed);
00302 } else if (!ptu->isInSpeedControlMode() & speed_control) {
00303 ptu->setSpeedControlMode(speed_control);
00304 }
00305 return true;
00306 }
00307
00308
00309 bool PTUNode::ok() {
00310 return ros::ok() && ptu->isConnected();
00311 }
00312
00313 void PTUNode::spinOnce() {
00314
00315
00316
00317
00318 bool done = ptu->hasHaltedAndReachedGoal();
00319 node_handle.setParam("reached_desired_position", done);
00320
00321
00322
00323 sensor_msgs::JointState state;
00324 asr_flir_ptu_driver::State msg;
00325 state.header.stamp = ros::Time::now();
00326 state.header.frame_id = (ptu->isInSpeedControlMode())? "speed_control" : "position_control";
00327 state.name.resize(2);
00328 state.position.resize(2);
00329 state.velocity.resize(2);
00330 state.name[0] = "ptu_pan";
00331 state.position[0] = ptu->getCurrentAngle(PAN);
00332 state.velocity[0] = ptu->getAngleSpeed(PAN);
00333 state.name[1] = "ptu_tilt";
00334 state.position[1] = ptu->getCurrentAngle(TILT);
00335 state.velocity[1] = ptu->getAngleSpeed(TILT);
00336 msg.state = state;
00337 msg.seq_num = seq_num;
00338 msg.finished = done;
00339 joint_pub.publish(msg);
00340 joint_pub_old.publish(state);
00341
00342
00343
00344 tf::Transform pan(tf::Quaternion(tf::Vector3(0,0,1), ptu->getCurrentAngle(PAN) * DEG_TO_RAD));
00345 tf::StampedTransform panStamped(pan, ros::Time::now(), ptu_pan_frame, ptu_pan_frame_rotated);
00346 tb_pan.sendTransform(panStamped);
00347
00348 tf::Transform tilt(tf::Quaternion(tf::Vector3(0,-1,0), ptu->getCurrentAngle(TILT) * DEG_TO_RAD));
00349 tf::StampedTransform tiltStamped(tilt, ros::Time::now(), ptu_tilt_frame, ptu_tilt_frame_rotated);
00350 tb_tilt.sendTransform(tiltStamped);
00351
00352 ros::spinOnce();
00353 }
00354
00355 int main(int argc, char **argv) {
00356 ros::init(argc, argv, "ptu_driver");
00357 ros::NodeHandle n("~");
00358 PTUNode* node = new PTUNode(n);
00359
00360 double update_rate = 100;
00361 n.getParam("update_rate", update_rate);
00362 ros::Rate loop_rate(update_rate);
00363 while (node->ok()) {
00364 node->spinOnce();
00365 loop_rate.sleep();
00366 }
00367 delete node;
00368
00369 }