$search
00001 /* -*- mode: C++ -*- 00002 * 00003 * Copyright (C) 2011 Austin Robot Technology 00004 * License: Modified BSD Software License Agreement 00005 * 00006 * $Id: device_impl.h 1539 2011-05-09 04:09:20Z jack.oquin $ 00007 */ 00008 00027 #ifndef __DEVICE_IMPL_H_ 00028 #define __DEVICE_IMPL_H_ 00029 00030 #include <ros/ros.h> 00031 00032 // device messages 00033 #include <nav_msgs/Odometry.h> 00034 #include <sensor_msgs/Imu.h> 00035 #include <art_msgs/BrakeCommand.h> 00036 #include <art_msgs/BrakeState.h> 00037 #include <art_msgs/Shifter.h> 00038 #include <art_msgs/SteeringCommand.h> 00039 #include <art_msgs/SteeringState.h> 00040 #include <art_msgs/ThrottleCommand.h> 00041 #include <art_msgs/ThrottleState.h> 00042 00043 #include "device_interface.h" 00044 00045 namespace device_interface 00046 { 00047 00049 class DeviceImu: public DeviceBase 00050 { 00051 public: 00052 00053 DeviceImu(ros::NodeHandle node): 00054 DeviceBase(node) 00055 { 00056 sub_ = node.subscribe("imu", 1, &DeviceImu::process, this, 00057 ros::TransportHints().tcpNoDelay(true)); 00058 } 00059 00060 virtual DeviceState state(ros::Time recently) 00061 { 00062 if (msg_.header.stamp > recently) 00063 return art_msgs::DriverState::RUNNING; 00064 else 00065 return art_msgs::DriverState::CLOSED; 00066 } 00067 00068 float value() 00069 { 00070 return msg_.linear_acceleration.x; // current acceleration 00071 } 00072 00073 private: 00074 00075 void process(const sensor_msgs::Imu::ConstPtr &msgIn) 00076 { 00077 msg_ = *msgIn; 00078 } 00079 00080 sensor_msgs::Imu msg_; // last message received 00081 }; 00082 00084 class DeviceOdom: public DeviceBase 00085 { 00086 public: 00087 00088 DeviceOdom(ros::NodeHandle node): 00089 DeviceBase(node) 00090 { 00091 sub_ = node.subscribe("odom", 1, &DeviceOdom::process, this, 00092 ros::TransportHints().tcpNoDelay(true)); 00093 } 00094 00095 virtual DeviceState state(ros::Time recently) 00096 { 00097 if (msg_.header.stamp > recently) 00098 return art_msgs::DriverState::RUNNING; 00099 else 00100 return art_msgs::DriverState::CLOSED; 00101 } 00102 00103 float value() 00104 { 00105 return msg_.twist.twist.linear.x; // current velocity 00106 } 00107 00108 private: 00109 00110 void process(const nav_msgs::Odometry::ConstPtr &msgIn) 00111 { 00112 msg_ = *msgIn; 00113 } 00114 00115 nav_msgs::Odometry msg_; // last message received 00116 }; 00117 00118 00120 class DeviceBrake: public ServoDeviceBase 00121 { 00122 public: 00123 00124 DeviceBrake(ros::NodeHandle node): 00125 ServoDeviceBase(node) 00126 { 00127 sub_ = node.subscribe("brake/state", 1, 00128 &DeviceBrake::process, this, 00129 ros::TransportHints().tcpNoDelay(true)); 00130 pub_ = node.advertise<art_msgs::BrakeCommand>("brake/cmd", 1); 00131 cmd_.request = art_msgs::BrakeCommand::Absolute; 00132 cmd_.position = 1.0; 00133 } 00134 00135 virtual float last_request() 00136 { 00137 return cmd_.position; // last position requested 00138 } 00139 00140 virtual void publish(float new_position, ros::Time cycle_time) 00141 { 00142 cmd_.header.stamp = cycle_time; 00143 cmd_.position = new_position; 00144 pub_.publish(cmd_); 00145 } 00146 00147 virtual DeviceState state(ros::Time recently) 00148 { 00149 if (msg_.header.stamp > recently) 00150 return art_msgs::DriverState::RUNNING; 00151 else 00152 return art_msgs::DriverState::CLOSED; 00153 } 00154 00155 virtual float value() 00156 { 00157 return msg_.position; // current brake position 00158 } 00159 00160 private: 00161 00162 void process(const art_msgs::BrakeState::ConstPtr &msgIn) 00163 { 00164 msg_ = *msgIn; 00165 } 00166 00167 art_msgs::BrakeCommand cmd_; // last command sent 00168 art_msgs::BrakeState msg_; // last message received 00169 }; 00170 00178 class DeviceShifter: public DeviceBase 00179 { 00180 public: 00181 00182 typedef art_msgs::Shifter::_gear_type Gear; 00183 00184 DeviceShifter(ros::NodeHandle node): 00185 DeviceBase(node), 00186 shift_duration_(1.0) 00187 { 00188 sub_ = node.subscribe("shifter/state", 1, 00189 &DeviceShifter::process, this, 00190 ros::TransportHints().tcpNoDelay(true)); 00191 pub_ = node.advertise<art_msgs::Shifter>("shifter/cmd", 1); 00192 msg_.gear = art_msgs::Shifter::Drive; 00193 } 00194 00196 bool busy(void) 00197 { 00198 return ((ros::Time::now() - shift_time_) < shift_duration_); 00199 } 00200 00202 bool is_reset(void) 00203 { 00204 return (msg_.relays == 0); 00205 } 00206 00207 void publish(Gear new_position, ros::Time cycle_time) 00208 { 00209 shift_time_ = cycle_time; 00210 cmd_.header.stamp = cycle_time; 00211 cmd_.gear = new_position; 00212 pub_.publish(cmd_); 00213 } 00214 00215 virtual DeviceState state(ros::Time recently) 00216 { 00217 if (msg_.header.stamp > recently) 00218 return art_msgs::DriverState::RUNNING; 00219 else 00220 return art_msgs::DriverState::CLOSED; 00221 } 00222 00223 Gear value() 00224 { 00225 return msg_.gear; // current gear number 00226 } 00227 00228 private: 00229 00230 void process(const art_msgs::Shifter::ConstPtr &msgIn) 00231 { 00232 msg_ = *msgIn; 00233 } 00234 00235 art_msgs::Shifter cmd_; // last command sent 00236 art_msgs::Shifter msg_; // last state message received 00237 ros::Publisher pub_; // command message publisher 00238 ros::Time shift_time_; // time last shift requested 00239 ros::Duration shift_duration_; // duration to hold relay 00240 }; 00241 00243 class DeviceSteering: public ServoDeviceBase 00244 { 00245 public: 00246 00247 DeviceSteering(ros::NodeHandle node): 00248 ServoDeviceBase(node) 00249 { 00250 sub_ = node.subscribe("steering/state", 1, 00251 &DeviceSteering::process, this, 00252 ros::TransportHints().tcpNoDelay(true)); 00253 pub_ = node.advertise<art_msgs::SteeringCommand>("steering/cmd", 1); 00254 cmd_.request = art_msgs::SteeringCommand::Degrees; 00255 cmd_.angle = 0.0; 00256 } 00257 00258 virtual float last_request() 00259 { 00260 return cmd_.angle; // last angle requested 00261 } 00262 00263 virtual void publish(float new_position, ros::Time cycle_time) 00264 { 00265 cmd_.header.stamp = cycle_time; 00266 cmd_.angle = new_position; 00267 pub_.publish(cmd_); 00268 } 00269 00270 virtual DeviceState state(ros::Time recently) 00271 { 00272 if (msg_.header.stamp > recently) 00273 return msg_.driver.state; 00274 else 00275 return art_msgs::DriverState::CLOSED; 00276 } 00277 00278 virtual float value() 00279 { 00280 return msg_.angle; // current steering angle 00281 } 00282 00283 private: 00284 00285 void process(const art_msgs::SteeringState::ConstPtr &msgIn) 00286 { 00287 msg_ = *msgIn; 00288 } 00289 00290 art_msgs::SteeringCommand cmd_; // last command sent 00291 art_msgs::SteeringState msg_; // last message received 00292 }; 00293 00295 class DeviceThrottle: public ServoDeviceBase 00296 { 00297 public: 00298 00299 DeviceThrottle(ros::NodeHandle node): 00300 ServoDeviceBase(node) 00301 { 00302 sub_ = node.subscribe("throttle/state", 1, 00303 &DeviceThrottle::process, this, 00304 ros::TransportHints().tcpNoDelay(true)); 00305 pub_ = node.advertise<art_msgs::ThrottleCommand>("throttle/cmd", 1); 00306 cmd_.request = art_msgs::ThrottleCommand::Absolute; 00307 cmd_.position = 0.0; 00308 } 00309 00310 virtual float last_request() 00311 { 00312 return cmd_.position; // last position requested 00313 } 00314 00315 virtual void publish(float new_position, ros::Time cycle_time) 00316 { 00317 cmd_.header.stamp = cycle_time; 00318 cmd_.position = new_position; 00319 pub_.publish(cmd_); 00320 } 00321 00322 virtual DeviceState state(ros::Time recently) 00323 { 00324 if (msg_.header.stamp > recently) 00325 return art_msgs::DriverState::RUNNING; 00326 else 00327 return art_msgs::DriverState::CLOSED; 00328 } 00329 00330 virtual float value() 00331 { 00332 return msg_.position; // current throttle position 00333 } 00334 00335 private: 00336 00337 void process(const art_msgs::ThrottleState::ConstPtr &msgIn) 00338 { 00339 msg_ = *msgIn; 00340 } 00341 00342 art_msgs::ThrottleCommand cmd_; // last command sent 00343 art_msgs::ThrottleState msg_; // last message received 00344 }; 00345 00346 }; // end device_interface namespace 00347 00348 #endif // __DEVICE_IMPL_H_