ptu46_node.cc
Go to the documentation of this file.
00001 #include <string>
00002 #include <ros/ros.h>
00003 #include <ptu46/ptu46_driver.h>
00004 #include <sensor_msgs/JointState.h>
00005 #include <diagnostic_updater/diagnostic_updater.h>
00006 #include <diagnostic_updater/publisher.h>
00007 
00008 namespace PTU46 {
00009 
00029 class PTU46_Node {
00030     public:
00031         PTU46_Node(ros::NodeHandle& node_handle);
00032         ~PTU46_Node();
00033 
00034         // Service Control
00035         void Connect();
00036         bool ok() {
00037             return m_pantilt != NULL;
00038         }
00039         void Disconnect();
00040 
00041         // Service Execution
00042         void spinOnce();
00043 
00044         // Callback Methods
00045         void SetGoal(const sensor_msgs::JointState::ConstPtr& msg);
00046 
00047         void produce_diagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat);
00048 
00049     protected:
00050         diagnostic_updater::Updater* m_updater;
00051         PTU46* m_pantilt;
00052         ros::NodeHandle m_node;
00053         ros::Publisher  m_joint_pub;
00054         ros::Subscriber m_joint_sub;
00055 };
00056 
00057 PTU46_Node::PTU46_Node(ros::NodeHandle& node_handle)
00058         :m_pantilt(NULL), m_node(node_handle) {
00059     m_updater = new diagnostic_updater::Updater();
00060     m_updater->setHardwareID("none"); 
00061     m_updater->add("PTU Status", this, &PTU46_Node::produce_diagnostics);
00062 }
00063 
00064 PTU46_Node::~PTU46_Node() {
00065     Disconnect();
00066     delete m_updater;
00067 }
00068 
00071 void PTU46_Node::Connect() {
00072     // If we are reconnecting, first make sure to disconnect
00073     if (ok()) {
00074         Disconnect();
00075     }
00076 
00077     // Query for serial configuration
00078     std::string port;
00079     m_node.param<std::string>("port", port, PTU46_DEFAULT_PORT);
00080     int baud;
00081     m_node.param("baud", baud, PTU46_DEFAULT_BAUD);
00082 
00083     // Connect to the PTU
00084     ROS_INFO("Attempting to connect to %s...", port.c_str());
00085     m_pantilt = new PTU46(port.c_str(), baud);
00086     ROS_ASSERT(m_pantilt != NULL);
00087     if (! m_pantilt->isOpen()) {
00088         ROS_ERROR("Could not connect to pan/tilt unit [%s]", port.c_str());
00089         Disconnect();
00090         return;
00091     }
00092     ROS_INFO("Connected!");
00093 
00094     m_node.setParam("min_tilt", m_pantilt->GetMin(PTU46_TILT));
00095     m_node.setParam("max_tilt", m_pantilt->GetMax(PTU46_TILT));
00096     m_node.setParam("min_tilt_speed", m_pantilt->GetMinSpeed(PTU46_TILT));
00097     m_node.setParam("max_tilt_speed", m_pantilt->GetMaxSpeed(PTU46_TILT));
00098     m_node.setParam("tilt_step", m_pantilt->GetResolution(PTU46_TILT));
00099 
00100     m_node.setParam("min_pan", m_pantilt->GetMin(PTU46_PAN));
00101     m_node.setParam("max_pan", m_pantilt->GetMax(PTU46_PAN));
00102     m_node.setParam("min_pan_speed", m_pantilt->GetMinSpeed(PTU46_PAN));
00103     m_node.setParam("max_pan_speed", m_pantilt->GetMaxSpeed(PTU46_PAN));
00104     m_node.setParam("pan_step", m_pantilt->GetResolution(PTU46_PAN));
00105 
00106 
00107     // Publishers : Only publish the most recent reading
00108     m_joint_pub = m_node.advertise
00109                   <sensor_msgs::JointState>("state", 1);
00110 
00111     // Subscribers : Only subscribe to the most recent instructions
00112     m_joint_sub = m_node.subscribe
00113                   <sensor_msgs::JointState>("cmd", 1, &PTU46_Node::SetGoal, this);
00114 
00115 }
00116 
00118 void PTU46_Node::Disconnect() {
00119     if (m_pantilt != NULL) {
00120         delete m_pantilt;   // Closes the connection
00121         m_pantilt = NULL;   // Marks the service as disconnected
00122     }
00123 }
00124 
00126 void PTU46_Node::SetGoal(const sensor_msgs::JointState::ConstPtr& msg) {
00127     if (! ok())
00128         return;
00129     double pan = msg->position[0];
00130     double tilt = msg->position[1];
00131     double panspeed = msg->velocity[0];
00132     double tiltspeed = msg->velocity[1];
00133     m_pantilt->SetPosition(PTU46_PAN, pan);
00134     m_pantilt->SetPosition(PTU46_TILT, tilt);
00135     m_pantilt->SetSpeed(PTU46_PAN, panspeed);
00136     m_pantilt->SetSpeed(PTU46_TILT, tiltspeed);
00137 }
00138 
00139 void PTU46_Node::produce_diagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat) {
00140      stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "All normal.");
00141      stat.add("PTU Mode", m_pantilt->GetMode()==PTU46_POSITION ? "Position" : "Velocity" );
00142 }
00143 
00144 
00149 void PTU46_Node::spinOnce() {
00150     if (! ok())
00151         return;
00152 
00153     // Read Position & Speed
00154     double pan  = m_pantilt->GetPosition(PTU46_PAN);
00155     double tilt = m_pantilt->GetPosition(PTU46_TILT);
00156 
00157     double panspeed  = m_pantilt->GetSpeed(PTU46_PAN);
00158     double tiltspeed = m_pantilt->GetSpeed(PTU46_TILT);
00159 
00160     // Publish Position & Speed
00161     sensor_msgs::JointState joint_state;
00162     joint_state.header.stamp = ros::Time::now();
00163     joint_state.name.resize(2);
00164     joint_state.position.resize(2);
00165     joint_state.velocity.resize(2);
00166     joint_state.name[0] ="pan";
00167     joint_state.position[0] = pan;
00168     joint_state.velocity[0] = panspeed;
00169     joint_state.name[1] ="tilt";
00170     joint_state.position[1] = tilt;
00171     joint_state.velocity[1] = tiltspeed;
00172     m_joint_pub.publish(joint_state);
00173 
00174     m_updater->update();
00175 
00176 }
00177 
00178 } // PTU46 namespace
00179 
00180 int main(int argc, char** argv) {
00181     ros::init(argc, argv, "ptu");
00182     ros::NodeHandle n("~");
00183 
00184     // Connect to PTU
00185     PTU46::PTU46_Node ptu_node = PTU46::PTU46_Node(n);
00186     ptu_node.Connect();
00187     if (! ptu_node.ok())
00188         return -1;
00189 
00190     // Query for polling frequency
00191     int hz;
00192     n.param("hz", hz, PTU46_DEFAULT_HZ);
00193     ros::Rate loop_rate(hz);
00194 
00195     while (ros::ok() && ptu_node.ok()) {
00196         // Publish position & velocity
00197         ptu_node.spinOnce();
00198 
00199         // Process a round of subscription messages
00200         ros::spinOnce();
00201 
00202         // This will adjust as needed per iteration
00203         loop_rate.sleep();
00204     }
00205 
00206     if (! ptu_node.ok()) {
00207         ROS_ERROR("pan/tilt unit disconncted prematurely");
00208         return -1;
00209     }
00210 
00211     return 0;
00212 }


ptu46
Author(s): Erik Karulf, David V. Lu!!
autogenerated on Fri Aug 28 2015 12:58:57