00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <uos_diffdrive_teleop.h>
00026
00027 Teleop::Teleop(){
00028 ros::NodeHandle n_private("~");
00029
00030 n_private.param("max_vel", max_vel, 1.0);
00031 n_private.param("max_rot_vel", max_rot_vel, 2.0);
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 n_private.param("acc_ahead_pos", acc_y.pos, 0.4);
00047 n_private.param("acc_ahead_neg", acc_y.neg, 0.8);
00048 n_private.param("acc_ahead_stop", acc_y.stop, 2.0);
00049
00050
00051 n_private.param("acc_rot_pos", acc_x.pos, 1.4);
00052 n_private.param("acc_rot_neg", acc_x.neg, 1.8);
00053 n_private.param("acc_rot_stop", acc_x.stop, 2.6);
00054
00055
00056 n_private.param("update_velocity_rate", update_velocity_rate, 0.01);
00057 n_private.param("update_inputs_rate", update_inputs_rate, 0.05);
00058
00059 vel_pub = n_.advertise<geometry_msgs::Twist>("cmd_vel", 1);
00060
00061 vel_timer = n_.createTimer(ros::Duration(update_velocity_rate), &Teleop::updateVelocity, this);
00062 key_timer = n_.createTimer(ros::Duration(update_inputs_rate), &Teleop::updateInputs, this);
00063
00064 velo.x = 0;
00065 velo.y = 0;
00066 }
00067
00068 void Teleop::updateVelocity(const ros::TimerEvent &t_event){
00069 ros::Duration delta = t_event.current_real - t_event.last_real;
00070
00071 double left = in.left;
00072 double forwards = in.forwards;
00073
00074 left = std::min(1.0, left);
00075 left = std::max(-1.0, left);
00076 forwards = std::min(1.0, forwards);
00077 forwards = std::max(-1.0, forwards);
00078
00079 velo.y = adaptVelocity(delta.toSec(), velo.y, forwards, acc_y.stop, acc_y.neg, acc_y.pos);
00080 velo.x = adaptVelocity(delta.toSec(), velo.x, left, acc_x.stop, acc_x.neg, acc_x.pos);
00081
00082
00083 velo.dyn_limit_y = max_vel * forwards;
00084 velo.dyn_limit_x = max_rot_vel * left;
00085
00086
00087 if((forwards < 0 && velo.y < velo.dyn_limit_y)
00088 || (forwards > 0 && velo.y > velo.dyn_limit_y))
00089 velo.y = velo.dyn_limit_y;
00090
00091
00092 if((left < 0 && velo.x < velo.dyn_limit_x)
00093 || (left > 0 && velo.x > velo.dyn_limit_x))
00094 velo.x = velo.dyn_limit_x;
00095
00096
00097 vel_cmd.linear.x = velo.y;
00098 vel_cmd.angular.z = velo.x;
00099
00100
00101 vel_pub.publish(vel_cmd);
00102
00103 }
00104
00105 void Teleop::updateInputs(const ros::TimerEvent &t_event){
00106 if(!in.updated){
00107 in.forwards = 0;
00108 in.left = 0;
00109 }
00110 in.updated = false;
00111 }
00112
00113 double Teleop::adaptVelocity(
00114 double delta_time,
00115 double velocity,
00116 double factor,
00117 double acc_stop,
00118 double acc_neg,
00119 double acc_pos)
00120 {
00121
00122 double new_velocity = velocity;
00123
00124 if(factor != 0) {
00125 if(factor > 0) {
00126
00127 if(velocity < 0)
00128 return (new_velocity += acc_stop * factor * delta_time) > -EPSILON_VELO ? 0 : new_velocity;
00129
00130 else
00131 return new_velocity + acc_pos * factor * delta_time;
00132 } else {
00133
00134 if(velocity > 0)
00135 return (new_velocity += acc_stop * factor * delta_time) < EPSILON_VELO ? 0 : new_velocity;
00136
00137 else
00138 return new_velocity + acc_pos * factor * delta_time;
00139 }
00140 }
00141 else {
00142
00143 if(velocity > 0)
00144 return (new_velocity += -acc_neg * delta_time) < EPSILON_VELO ? 0 : new_velocity;
00145 else if(velocity < 0)
00146 return (new_velocity += acc_neg * delta_time) > -EPSILON_VELO ? 0 : new_velocity;
00147 return 0;
00148 }
00149 }