Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef MOTION_CONTROLLER_BASE_H
00023 #define MOTION_CONTROLLER_BASE_H
00024
00025 #include <ros/ros.h>
00026 #include <tf/transform_broadcaster.h>
00027 #include <geometry_msgs/Twist.h>
00028 #include <geometry_msgs/Pose2D.h>
00029 #include <stdr_msgs/KinematicMsg.h>
00030
00031 #include <ctime>
00032
00037 namespace stdr_robot {
00038
00039
00044 class MotionController {
00045
00046 public:
00047
00053 virtual void velocityCallback(const geometry_msgs::Twist& msg)
00054 {
00055 _currentTwist = msg;
00056 sampleVelocities();
00057 }
00058
00075 virtual void sampleVelocities(void)
00076 {
00077 float ux = _currentTwist.linear.x;
00078 float uy = _currentTwist.linear.y;
00079 float w = _currentTwist.angular.z;
00080
00081 float sample_ux =
00082 _motion_parameters.a_ux_ux * ux * ux +
00083 _motion_parameters.a_ux_uy * uy * uy +
00084 _motion_parameters.a_ux_w * w * w;
00085 _currentTwist.linear.x += sampleNormal(sqrt(sample_ux));
00086
00087 float sample_uy =
00088 _motion_parameters.a_uy_ux * ux * ux +
00089 _motion_parameters.a_uy_uy * uy * uy +
00090 _motion_parameters.a_uy_w * w * w;
00091 _currentTwist.linear.y += sampleNormal(sqrt(sample_uy));
00092
00093 float sample_w =
00094 _motion_parameters.a_w_ux * ux * ux +
00095 _motion_parameters.a_w_uy * uy * uy +
00096 _motion_parameters.a_w_w * w * w;
00097 _currentTwist.angular.z += sampleNormal(sqrt(sample_w));
00098
00099 float sample_g =
00100 _motion_parameters.a_g_ux * ux * ux +
00101 _motion_parameters.a_g_uy * uy * uy +
00102 _motion_parameters.a_g_w * w * w;
00103 _currentTwist.angular.z += sampleNormal(sqrt(sample_g));
00104 }
00105
00106
00111 virtual void stop(void)
00112 {
00113 _currentTwist.linear.x = 0;
00114 _currentTwist.linear.y = 0;
00115 _currentTwist.linear.z = 0;
00116 _currentTwist.angular.x = 0;
00117 _currentTwist.angular.y = 0;
00118 _currentTwist.angular.z = 0;
00119 }
00120
00126 virtual void calculateMotion(const ros::TimerEvent& event) = 0;
00127
00132 inline geometry_msgs::Pose2D getPose(void)
00133 {
00134 return _pose;
00135 }
00136
00142 inline void setPose(geometry_msgs::Pose2D new_pose)
00143 {
00144 _pose.x = new_pose.x;
00145 _pose.y = new_pose.y;
00146 _pose.theta = new_pose.theta;
00147 }
00148
00153 inline geometry_msgs::Twist getVelocity() {
00154 return _currentTwist;
00155 }
00156
00161 virtual ~MotionController(void)
00162 {
00163 }
00164
00170 float sampleNormal(float sigma)
00171 {
00172 float tmp = 0;
00173 for (unsigned int i = 0 ; i < 12 ; i++)
00174 {
00175 float sample = (rand() % 100000) / 50000.0 - 1.0;
00176 tmp += sample * sigma;
00177 }
00178 return tmp / 2.0;
00179 }
00180
00181
00182 protected:
00183
00191 MotionController(
00192 const geometry_msgs::Pose2D& pose,
00193 tf::TransformBroadcaster& tf,
00194 const std::string& name,
00195 ros::NodeHandle& n,
00196 const stdr_msgs::KinematicMsg params
00197 )
00198 : _tfBroadcaster(tf),
00199 _freq(0.1),
00200 _namespace(name),
00201 _pose(pose),
00202 _motion_parameters(params)
00203 {
00204 _velocitySubscrider = n.subscribe(
00205 _namespace + "/cmd_vel",
00206 1,
00207 &MotionController::velocityCallback,
00208 this);
00209
00210 srand(time(NULL));
00211 }
00212
00213 protected:
00214
00216 const std::string& _namespace;
00218 ros::Subscriber _velocitySubscrider;
00220 ros::Duration _freq;
00222 ros::Timer _calcTimer;
00224 tf::TransformBroadcaster& _tfBroadcaster;
00226 geometry_msgs::Pose2D _pose;
00228 geometry_msgs::Twist _currentTwist;
00230 stdr_msgs::KinematicMsg _motion_parameters;
00231 };
00232
00233 typedef boost::shared_ptr<MotionController> MotionControllerPtr;
00234
00235 }
00236
00237
00238 #endif