PTUTracker.cpp
Go to the documentation of this file.
00001 
00018 #include <ros/ros.h>
00019 #include <asr_msgs/AsrObject.h>
00020 #include <geometry_msgs/PoseStamped.h>
00021 #include <sensor_msgs/JointState.h>
00022 #include <string>
00023 #include <stdio.h>
00024 #include <iostream>
00025 #include <boost/thread.hpp>
00026 #include <boost/date_time/posix_time/posix_time.hpp>
00027 #include <tf/transform_listener.h>
00028 #include <tf/transform_broadcaster.h>
00029 #include <tf/transform_datatypes.h>
00030 #include <unistd.h>
00031 #include <termios.h>
00032 
00033 #define RAD_TO_DEG (180.0 / M_PI)
00034 #define DEG_TO_RAD (1 / RAD_TO_DEG)
00035 
00036 class PTUTracker {
00037     
00038     struct Point3f{
00039         float x, y, z;
00040     };
00041     struct Point2f{
00042         float x, y;
00043     };
00044 public:
00045         ros::NodeHandle nh;
00046 
00047         // Publications / Subscriptions
00048         ros::Subscriber fob_sub;
00049         ros::Subscriber ptu_sub;
00050         ros::Publisher ptu_pub;
00051 
00052         //Param names
00053         std::string ptu_state_cmd, ptu_state, fob_topic, fob_tracking_point_left, fob_tracking_point_right;
00054         int panAmount, tiltAmount;
00055 
00056         //States
00057         std::vector<double> ptuPosition;
00058 
00059         geometry_msgs::Pose fob_pose_left;
00060         geometry_msgs::Pose fob_pose_right;
00061 
00062         geometry_msgs::PointStamped ptuPoint;
00063         geometry_msgs::PointStamped fobPoint;
00064 
00065         struct termios oldt;
00066 
00067 
00068         tf::TransformListener tf;
00069         tf::TransformBroadcaster tb;
00070 
00071         //FOB Callback
00072         void fobCB(const asr_msgs::AsrObject& fob_msg) {
00073 
00074           if(!fob_msg.sampledPoses.size()){
00075         std::cerr << "Got a AsrObject without poses." << std::endl;
00076             std::exit(1);    
00077           }
00078 
00079           if (!fob_msg.identifier.empty() && strcmp(fob_msg.identifier.c_str(), fob_tracking_point_left.c_str()) == 0) {
00080             ROS_DEBUG("fob left message recieved");
00081             fob_pose_left = fob_msg.sampledPoses.front().pose;
00082           }else if (!fob_msg.identifier.empty() && strcmp(fob_msg.identifier.c_str(), fob_tracking_point_right.c_str()) == 0) {
00083             ROS_DEBUG("fob right message recieved");
00084             fob_pose_right = fob_msg.sampledPoses.front().pose;
00085           }
00086         }
00087 
00088         //PTU Callback
00089         void ptuCB(const sensor_msgs::JointState& ptu_msg) {
00090             ptuPosition = ptu_msg.position;
00091         }
00092 
00093         //Initializations and configure
00094         PTUTracker(ros::NodeHandle nh){
00095             this->nh = nh;
00096             nh.getParam("ptu_pub_topic", ptu_state_cmd);
00097             nh.getParam("ptu_sub_topic", ptu_state);
00098             nh.getParam("fob_sub_topic", fob_topic);
00099             nh.getParam("fob_tracking_point_left", fob_tracking_point_left);
00100             nh.getParam("fob_tracking_point_right", fob_tracking_point_right);
00101 
00102             nh.getParam("panAmount", panAmount);
00103             nh.getParam("tiltAmount", tiltAmount);
00104 
00105             std::string fob_frame, ptu_frame;
00106             nh.getParam("tracker_frame", fob_frame);
00107             nh.getParam("ptu_base_frame", ptu_frame);
00108 
00109             fob_sub = nh.subscribe(fob_topic, 1, &PTUTracker::fobCB, this);
00110             ptu_sub = nh.subscribe("/asr_flir_ptu_driver/state", 1, &PTUTracker::ptuCB, this);
00111             ptu_pub = nh.advertise<sensor_msgs::JointState>(ptu_state_cmd, 5);
00112 
00113             fobPoint.header.frame_id = fob_frame;
00114             fobPoint.header.stamp = ros::Time(0);
00115             ptuPoint.header.frame_id = ptu_frame;
00116             ptuPoint.header.stamp = ros::Time(0);
00117 
00118             boost::thread trackerThread(spin, this);
00119             ros::spin();
00120             trackerThread.interrupt();
00121 
00122             //reapply the old Terminal settings
00123             tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
00124 
00125         }
00126 
00127         Point2f toSphereCoords(geometry_msgs::PointStamped p) {
00128             Point3f temp;
00129             temp.x = p.point.x;
00130             temp.y = p.point.y;
00131             temp.z = p.point.z;
00132             
00133             return toSphereCoords(temp);
00134         }
00135 
00136         Point2f toSphereCoords(Point3f pt) {
00137             Point2f pantilt;
00138             Point3f p;
00139             p.x = -pt.y;
00140             p.y = -pt.x;
00141             p.z = -pt.z;
00142             double panAngle = (p.x < 0)? 1 : -1;
00143             panAngle *= acos(-p.y / (sqrt(p.x * p.x + p.y * p.y))) * RAD_TO_DEG;
00144 
00145             double tiltAngle = (p.z > 0)? -1 : 1;
00146             tiltAngle *= acos(-p.y / (sqrt(p.y * p.y + p.z * p.z))) * RAD_TO_DEG;
00147 
00148             pantilt.x = panAngle;
00149             pantilt.y = tiltAngle;
00150 
00151             return pantilt;
00152         }
00153 
00154         void movePTU(char c){
00155             if(c!='l' && c !='r'){
00156                     return;
00157             }
00158 
00159             //transformation into sphere coords is only possible if the point is in the PTU frame
00160             if(c == 'l'){
00161                 fobPoint.point.x = fob_pose_left.position.x;
00162                 fobPoint.point.y = fob_pose_left.position.y;
00163                 fobPoint.point.z = fob_pose_left.position.z;
00164             }else if(c == 'r'){
00165                 fobPoint.point.x = fob_pose_right.position.x;
00166                 fobPoint.point.y = fob_pose_right.position.y;
00167                 fobPoint.point.z = fob_pose_right.position.z;
00168             }
00169             tf.transformPoint(ptuPoint.header.frame_id, fobPoint, ptuPoint);
00170             Point2f pantiltTarget = toSphereCoords(ptuPoint);
00171             rotPTUAbsolute(pantiltTarget.x, pantiltTarget.y);
00172 
00173         }
00174         void rotPTUAbsolute(double pan, double tilt){
00175             ROS_INFO("Target pan tilt angle: ([%f  %f])", pan, tilt);
00176 
00177             sensor_msgs::JointState pantiltState;
00178             pantiltState.header.stamp = ros::Time::now();
00179 
00180             pantiltState.name.push_back("pan");
00181             pantiltState.name.push_back("tilt");
00182 
00183             pantiltState.position.push_back(pan);
00184             pantiltState.position.push_back(tilt);
00185 
00186             pantiltState.velocity.push_back(0);
00187             pantiltState.velocity.push_back(0);
00188 
00189             ptu_pub.publish(pantiltState);
00190         }
00191         void rotPTURelative(double pan, double tilt){
00192             pan = pan + ptuPosition[0];
00193             tilt = tilt + ptuPosition[1];
00194             rotPTUAbsolute(pan, tilt);
00195         }
00196 
00197         int getch(void)
00198         {
00199             //overlays echo from Terminal
00200             int ch;
00201             struct termios newt;
00202             tcgetattr(STDIN_FILENO, &oldt);
00203             newt = oldt;
00204             newt.c_lflag &= ~(ICANON | ECHO);
00205             tcsetattr(STDIN_FILENO, TCSANOW, &newt);
00206             ch = getchar();
00207             tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
00208             return ch;
00209         }
00210 
00211         int getKey()
00212         {
00213            int result=getch();
00214            if(result==0){
00215               result=256+getch();
00216            }
00217            return result;
00218         }
00219 
00220         static void spin(PTUTracker* tracker){
00221             std::string input;
00222             ROS_INFO("Press <l> to move PTU to left tracker.");
00223             ROS_INFO("Press <r> to move PTU to right tracker.");
00224             ROS_INFO("Use Arrowkeys to move PTU (do not hold key down).");
00225 
00226             while (true){
00227                char c = tracker->getKey();
00228 
00229                if(c == 'l' || c == 'r'){
00230                     tracker->movePTU(c);
00231                }else if(c == 65){
00232                     tracker->rotPTURelative(0,tracker->tiltAmount);
00233                }else if(c == 66){
00234                    tracker->rotPTURelative(0,-tracker->tiltAmount);
00235                }else if(c == 67){
00236                    tracker->rotPTURelative(-tracker->panAmount,0);
00237                }else if(c == 68){
00238                    tracker->rotPTURelative(tracker->panAmount,0);
00239                }
00240                boost::this_thread::sleep(boost::posix_time::milliseconds(100));
00241             }
00242         }
00243 };
00244 
00245 int main(int argc, char** argv)
00246 {
00247   ros::init(argc, argv, "ptu_tracker");
00248   ros::NodeHandle nh("~");
00249   new ::PTUTracker(nh);
00250   return 0;
00251 }


asr_flock_of_birds_tracking
Author(s): Engelmann Stephan, Heller Florian, Meißner Pascal, Stöckle Patrick, Wittenbeck Valerij
autogenerated on Sat Jun 8 2019 19:01:41