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
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
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
00059
00060
00061
00062
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
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
00122
00123
00124
00125
00126
00127
00128
00129
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
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 }