PTUController.cpp
Go to the documentation of this file.
00001 #include "ptu_controller/PTUController.h"
00002 namespace asr_flir_ptu_controller
00003 {
00004     const double PTUController::RAD_TO_DEG = 180.0 / M_PI;
00005 
00006     PTUController::PTUController(ros::NodeHandle& node_handle, std::string name):
00007         nodeHandle(node_handle),
00008         simpleActionServer(name, false) {
00009         //register the goal and feeback callbacks
00010         simpleActionServer.registerGoalCallback(boost::bind(&PTUController::goalCB, this));
00011         simpleActionServer.registerPreemptCallback(boost::bind(&PTUController::preemptCB, this));
00012 
00013         ROS_DEBUG("PTUController, %s", ros::this_node::getName().c_str());
00014         PTUController::setSettings();
00015         stateCommandPublisher = nodeHandle.advertise<asr_flir_ptu_driver::State>(getDefaultStateCmdTopicName(), 100);
00016         stateSubscriber =  nodeHandle.subscribe<asr_flir_ptu_driver::State>(getDefaultStateTopicName(), 100, &PTUController::currentStateArrived, this);
00017 
00018         stateCommandMessage.header.seq = 0;
00019         stateCommandMessage.name.push_back("pan");
00020         stateCommandMessage.name.push_back("tilt");
00021         stateCommandMessage.velocity.push_back(0);
00022         stateCommandMessage.velocity.push_back(0);
00023         lastStateTime = ros::Time::now();
00024         simpleActionServer.start();
00025         validate_client= nodeHandle.serviceClient<asr_flir_ptu_driver::Validate>(validation_service);
00026         alive = nodeHandle.serviceClient<std_srvs::Empty>(alive_service, true);
00027         seq_num = 0;
00028     }
00029 
00030     PTUController::~PTUController() {
00031     }
00032     void PTUController::currentStateArrived(const asr_flir_ptu_driver::State::ConstPtr& msg) {
00033         if (msg->seq_num == seq_num) {
00034             current_pan = msg->state.position[0];
00035             current_tilt = msg->state.position[1];
00036             lastStateTime = ros::Time::now();
00037             if (simpleActionServer.isActive()) {
00038                 //update joint state
00039                 sensor_msgs::JointState state;
00040                 state.header.stamp = lastStateTime;
00041                 state.name.resize(2);
00042                 state.position.resize(2);
00043                 state.velocity.resize(2);
00044                 state.name[0] = "ptu_pan";
00045                 state.position[0] = getCurrentPan();
00046                 state.velocity[0] = 0;
00047                 state.name[1] = "ptu_tilt";
00048                 state.position[1] = getCurrentTilt();
00049                 state.velocity[1] = 0;
00050                 simpleActionServerFeedback.base_joint = state;
00051 
00052                 double squaredSums = pow( desired_pan - current_pan , 2.0) + pow(desired_tilt - current_tilt, 2.0);
00053                 double currentDistance = sqrt(squaredSums);
00054                 simpleActionServerFeedback.percentage = 1.0 - currentDistance / startDistance;
00055                 ROS_DEBUG_STREAM("Covered " << simpleActionServerFeedback.percentage << "% of the way to my goal.");
00056                 simpleActionServer.publishFeedback(simpleActionServerFeedback);
00057 
00058                 //if ((fabs(getCurrentPan() - desired_pan) < getToleranceValue() ) &&
00059                 //    (fabs(getCurrentTilt() - desired_tilt) < getToleranceValue() )) {
00060 
00061                 //This might cause a problem when a new goal is sent but the variable is still true from the previouse one - not sure atm if this can happen
00062                 //bool reached_goal_and_halted;
00063                 if(msg->finished) {
00064                     simpleActionServerResult.end_joint = state;
00065                     ROS_INFO("Succeeded");
00066                     simpleActionServer.setSucceeded(simpleActionServerResult);
00067                 } else {
00068                     count++;
00069                     if (count > getMaxSteps()) {
00070                         simpleActionServerResult.end_joint = state;
00071                         ROS_ERROR("Aborted: More steps taken than allowed. MaxSteps: %d", getMaxSteps());
00072                         simpleActionServer.setAborted(simpleActionServerResult);
00073                     }
00074                 }
00075             }
00076         }
00077     }
00078 
00079     void PTUController::goalCB() {
00080         ROS_DEBUG("Goal callback");
00081         if(!alive)
00082         {
00083             ROS_ERROR("The PTU does not responde. Please check the PTU-Node");
00084             simpleActionServer.setAborted(simpleActionServerResult);
00085         }
00086 
00087         target_joint = simpleActionServer.acceptNewGoal()->target_joint;
00088         double pan_candidate          = target_joint.position[0];
00089         double tilt_candidate         = target_joint.position[1];
00090         double pan_speed     = target_joint.velocity[0];
00091         double tilt_speed    = target_joint.velocity[1];
00092         //seems it only uses non-speed mode; not sure why this is needed
00093         if (pan_speed != 0 || tilt_speed != 0)
00094         {
00095             ROS_ERROR("The speed is not 0,0!");
00096             simpleActionServer.setAborted(simpleActionServerResult);
00097         }
00098 
00099         asr_flir_ptu_driver::Validate values_for_validation;
00100         values_for_validation.request.pan = pan_candidate;
00101         values_for_validation.request.tilt = tilt_candidate;
00102         values_for_validation.request.margin = getMargin();
00103         if(validate_client.call(values_for_validation)) {
00104             if(values_for_validation.response.is_valid)
00105             {
00106                 desired_pan = values_for_validation.response.new_pan;
00107                 desired_tilt = values_for_validation.response.new_tilt;
00108             }
00109             else {
00110                 ROS_ERROR("Values for pan %f and tilt %f do not lie within the working area of the ptu, neither do they lie within the margin %f out of the working area"
00111                           , pan_candidate, tilt_candidate, getMargin());
00112                 simpleActionServer.setAborted(simpleActionServerResult);
00113             }
00114         }
00115         else {
00116             ROS_ERROR("Failed to contact Validate service");
00117             simpleActionServer.setAborted(simpleActionServerResult);
00118         }
00119 
00120 
00121         //ros::Time current_time = ros::Time::now();
00122         //double time_difference = current_time.toSec() - lastStateTime.toSec();
00123 
00124         //Falsch: Hier bitte separaten watchdog einbauen
00125         //if (time_difference > getTimeToWait()) {
00126 
00127 
00128         //Alive is a service client with steady connection to the supplying PTUNode. A check with "if" of this client indicates if the PTUNode instance is still alive or not
00129         //For more information please check http://wiki.ros.org/roscpp/Overview/Services point 2.1
00130 
00131         seq_num++;
00132         asr_flir_ptu_driver::State msg;
00133         stateCommandMessage.position.clear();
00134         stateCommandMessage.position.push_back(desired_pan);
00135         stateCommandMessage.position.push_back(desired_tilt);
00136         //Wenn panSpeed und tiltSpeed sowieso nur übergeben wird wenn beide = 0 sind, warum werden sie dann überhaupt übergeben?
00137         stateCommandMessage.velocity.push_back(pan_speed);
00138         stateCommandMessage.velocity.push_back(tilt_speed);
00139         stateCommandMessage.header.stamp = ros::Time::now();
00140         msg.state = stateCommandMessage;
00141         msg.seq_num = seq_num;
00142         msg.no_check_forbidden_area = false;
00143         stateCommandPublisher.publish(msg);
00144         ROS_DEBUG("pan:%f , tilt:%f, panSpeed:%f, tiltSpeed:%f", desired_pan, desired_tilt, pan_speed, tilt_speed);
00145         count = 0;
00146         double squared_sums = pow( desired_pan - current_pan , 2.0) + pow(desired_tilt - current_tilt, 2.0);
00147         startDistance = sqrt(squared_sums);
00148     }
00149 
00150     void PTUController::preemptCB()  {
00151         ROS_INFO("Preemted");
00152         simpleActionServer.setPreempted();
00153     }
00157     void PTUController::setSettings() {
00158         nodeHandle.getParam("timeToWait", timeToWait);
00159         nodeHandle.getParam("margin", margin);
00160         nodeHandle.getParam("maxSteps", maxSteps);
00161         nodeHandle.getParam("tolerance", tolerance);
00162         nodeHandle.getParam("topicName", topicName);
00163         nodeHandle.getParam("commandTopicName", commandTopicName);
00164         nodeHandle.getParam("serviceValidation", validation_service);
00165         nodeHandle.getParam("serviceAlive", alive_service);
00166     }
00167     double PTUController::getMaximumPan(){
00168         return max_pan;
00169     }
00170     double PTUController::getMinimumPan() {
00171         return min_pan;
00172     }
00173 
00174     double PTUController::getMaximumTilt(){
00175         return max_tilt;
00176     }
00177     double PTUController::getMinimumTilt(){
00178         return min_tilt;
00179     }
00180 
00181     double PTUController::getCurrentPan() {
00182         return current_pan;
00183     }
00184     double PTUController::getCurrentTilt(){
00185         return current_tilt;
00186     }
00187 
00188     std::string PTUController::getDefaultStateCmdTopicName() {
00189         return topicName;
00190     }
00191     std::string PTUController::getDefaultStateTopicName() {
00192         return commandTopicName;
00193     }
00194     double PTUController::getToleranceValue() {
00195         return tolerance;
00196     }
00197     double PTUController::getTimeToWait() {
00198         return timeToWait;
00199     }
00200     int PTUController::getMaxSteps() {
00201         return maxSteps;
00202     }
00203     double PTUController::getMargin() const
00204     {
00205         return margin;
00206     }
00207 
00208     void PTUController::setMargin(double value)
00209     {
00210         margin = value;
00211     }
00212 }
00213 
00214 int main(int argc, char** argv)
00215 {
00216     ros::init(argc, argv, "ptu_controller_actionlib");
00217     ros::NodeHandle n("~");
00218     std::string actionServerName;
00219     n.getParam("actionServerName", actionServerName);
00220     asr_flir_ptu_controller::PTUController * nodeActionlib = new asr_flir_ptu_controller::PTUController(n, actionServerName);
00221     ros::spin();
00222     return 0;
00223 }


asr_flir_ptu_controller
Author(s): Ralph Schleicher, Patrick Schlosser
autogenerated on Thu Jun 6 2019 21:24:15