PTUNode.cpp
Go to the documentation of this file.
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     //goal_not_reached = false;
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     //Required for some external packages, not asr_flir_ptu_controller (maybe fix there if time left, they expect the old sensor_msgs::JointState instead of asr_flir_ptu_driver::State)
00048     joint_pub_old = node_handle.advertise<sensor_msgs::JointState>(topic_state, 1);
00049 
00050     //name is a placeholder for testing
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     //goal_fulfilled_service = node_handle.advertiseService("/goal_fulfilled", &PTUNode::goalFulfilled, this);
00055 
00056     //Required for some external packages (not asr_flir_ptu_driver). If time left, check if really necessary in the other packages.
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         //goal_not_reached = true;
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     //Reicht das, brauch ich die normale Überprüfung nicht?
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     //Empty because service is meant to be used with a steady connection (see http://wiki.ros.org/roscpp/Overview/Services point 2.1) to check if PTUNode is working/running
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       //get all ptu settings
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       // configurate PTU driver with parameters loaded via node handle
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       // load names of coordinate systems
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       // load names of ROS topics
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       // load names of ROS services
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       //add the namespace of the asr_flir_ptu_driver to the list of ptu namespaces. This is necessary to 'find' the PTU with the gui
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         //not critical, but needs more testing: does PTU keep current speed when it's switched to position mode?
00296         //this code assumes it does
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 //check to see if PTU is still connected
00309 bool PTUNode::ok() {
00310         return ros::ok() && ptu->isConnected();
00311 }
00312 
00313 void PTUNode::spinOnce() {
00314     //set stopped and whether or not the ptu is in speed control mode
00315     //PROBLEM HERE: When new state arrives it can have wrong value on the first publishing when goal that was executed before succeeded
00316 
00317     //if(goal_not_reached || ptu->isInSpeedControlMode()) {
00318         bool done = ptu->hasHaltedAndReachedGoal();
00319         node_handle.setParam("reached_desired_position", done);
00320         //if(done) goal_not_reached = false;
00321 
00322         //update joint state
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"; //mostly for debugging
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     // publish updated PTU coordinate system
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 }


asr_flir_ptu_driver
Author(s): Valerij Wittenbeck, Joachim Gehrung, Pascal Meißner, Patrick Schlosser
autogenerated on Thu Jun 6 2019 21:16:45