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
00035 void Connect();
00036 bool ok() {
00037 return m_pantilt != NULL;
00038 }
00039 void Disconnect();
00040
00041
00042 void spinOnce();
00043
00044
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
00073 if (ok()) {
00074 Disconnect();
00075 }
00076
00077
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
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
00108 m_joint_pub = m_node.advertise
00109 <sensor_msgs::JointState>("state", 1);
00110
00111
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;
00121 m_pantilt = NULL;
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
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
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 }
00179
00180 int main(int argc, char** argv) {
00181 ros::init(argc, argv, "ptu");
00182 ros::NodeHandle n("~");
00183
00184
00185 PTU46::PTU46_Node ptu_node = PTU46::PTU46_Node(n);
00186 ptu_node.Connect();
00187 if (! ptu_node.ok())
00188 return -1;
00189
00190
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
00197 ptu_node.spinOnce();
00198
00199
00200 ros::spinOnce();
00201
00202
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 }