turtlebot3_fake.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright 2016 ROBOTIS CO., LTD.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16 
17 /* Authors: Yoonseok Pyo */
18 
20 
22 : nh_priv_("~")
23 {
24  //Init fake turtlebot node
25  bool init_result = init();
26  ROS_ASSERT(init_result);
27 }
28 
30 {
31 }
32 
33 /*******************************************************************************
34 * Init function
35 *******************************************************************************/
37 {
38  // initialize ROS parameter
39 
40  std::string robot_model = nh_.param<std::string>("tb3_model", "");
41 
42  if (!robot_model.compare("burger"))
43  {
44  wheel_seperation_ = 0.160;
45  turning_radius_ = 0.080;
46  robot_radius_ = 0.105;
47  }
48  else if (!robot_model.compare("waffle") || !robot_model.compare("waffle_pi"))
49  {
50  wheel_seperation_ = 0.287;
51  turning_radius_ = 0.1435;
52  robot_radius_ = 0.220;
53  }
54 
55  nh_.param("wheel_left_joint_name", joint_states_name_[LEFT], std::string("wheel_left_joint"));
56  nh_.param("wheel_right_joint_name", joint_states_name_[RIGHT], std::string("wheel_right_joint"));
57  nh_.param("joint_states_frame", joint_states_.header.frame_id, std::string("base_footprint"));
58  nh_.param("odom_frame", odom_.header.frame_id, std::string("odom"));
59  nh_.param("base_frame", odom_.child_frame_id, std::string("base_footprint"));
60 
61  // initialize variables
62  wheel_speed_cmd_[LEFT] = 0.0;
63  wheel_speed_cmd_[RIGHT] = 0.0;
66  cmd_vel_timeout_ = 1.0;
67  last_position_[LEFT] = 0.0;
68  last_position_[RIGHT] = 0.0;
69  last_velocity_[LEFT] = 0.0;
70  last_velocity_[RIGHT] = 0.0;
71 
72  double pcov[36] = { 0.1, 0, 0, 0, 0, 0,
73  0, 0.1, 0, 0, 0, 0,
74  0, 0, 1e6, 0, 0, 0,
75  0, 0, 0, 1e6, 0, 0,
76  0, 0, 0, 0, 1e6, 0,
77  0, 0, 0, 0, 0, 0.2};
78  memcpy(&(odom_.pose.covariance),pcov,sizeof(double)*36);
79  memcpy(&(odom_.twist.covariance),pcov,sizeof(double)*36);
80 
81  odom_pose_[0] = 0.0;
82  odom_pose_[1] = 0.0;
83  odom_pose_[2] = 0.0;
84 
85  odom_vel_[0] = 0.0;
86  odom_vel_[1] = 0.0;
87  odom_vel_[2] = 0.0;
88 
89  joint_states_.name.push_back(joint_states_name_[LEFT]);
90  joint_states_.name.push_back(joint_states_name_[RIGHT]);
91  joint_states_.position.resize(2,0.0);
92  joint_states_.velocity.resize(2,0.0);
93  joint_states_.effort.resize(2,0.0);
94 
95  // initialize publishers
96  joint_states_pub_ = nh_.advertise<sensor_msgs::JointState>("joint_states", 100);
97  odom_pub_ = nh_.advertise<nav_msgs::Odometry>("odom", 100);
98 
99  // initialize subscribers
101 
103 
104  return true;
105 }
106 
107 /*******************************************************************************
108 * Callback function for cmd_vel msg
109 *******************************************************************************/
110 void Turtlebot3Fake::commandVelocityCallback(const geometry_msgs::TwistConstPtr cmd_vel_msg)
111 {
113 
114  goal_linear_velocity_ = cmd_vel_msg->linear.x;
115  goal_angular_velocity_ = cmd_vel_msg->angular.z;
116 
119 }
120 
121 /*******************************************************************************
122 * Calculate the odometry
123 *******************************************************************************/
125 {
126  double wheel_l, wheel_r; // rotation value of wheel [rad]
127  double delta_s, delta_theta;
128  double v[2], w[2];
129 
130  wheel_l = wheel_r = 0.0;
131  delta_s = delta_theta = 0.0;
132 
133  v[LEFT] = wheel_speed_cmd_[LEFT];
134  w[LEFT] = v[LEFT] / WHEEL_RADIUS; // w = v / r
136  w[RIGHT] = v[RIGHT] / WHEEL_RADIUS;
137 
138  last_velocity_[LEFT] = w[LEFT];
139  last_velocity_[RIGHT] = w[RIGHT];
140 
141  wheel_l = w[LEFT] * diff_time.toSec();
142  wheel_r = w[RIGHT] * diff_time.toSec();
143 
144  if(isnan(wheel_l))
145  {
146  wheel_l = 0.0;
147  }
148 
149  if(isnan(wheel_r))
150  {
151  wheel_r = 0.0;
152  }
153 
154  last_position_[LEFT] += wheel_l;
155  last_position_[RIGHT] += wheel_r;
156 
157  delta_s = WHEEL_RADIUS * (wheel_r + wheel_l) / 2.0;
158  delta_theta = WHEEL_RADIUS * (wheel_r - wheel_l) / wheel_seperation_;
159 
160  // compute odometric pose
161  odom_pose_[0] += delta_s * cos(odom_pose_[2] + (delta_theta / 2.0));
162  odom_pose_[1] += delta_s * sin(odom_pose_[2] + (delta_theta / 2.0));
163  odom_pose_[2] += delta_theta;
164 
165  // compute odometric instantaneouse velocity
166  odom_vel_[0] = delta_s / diff_time.toSec(); // v
167  odom_vel_[1] = 0.0;
168  odom_vel_[2] = delta_theta / diff_time.toSec(); // w
169 
170  odom_.pose.pose.position.x = odom_pose_[0];
171  odom_.pose.pose.position.y = odom_pose_[1];
172  odom_.pose.pose.position.z = 0;
173  odom_.pose.pose.orientation = tf::createQuaternionMsgFromYaw(odom_pose_[2]);
174 
175  // We should update the twist of the odometry
176  odom_.twist.twist.linear.x = odom_vel_[0];
177  odom_.twist.twist.angular.z = odom_vel_[2];
178 
179  return true;
180 }
181 
182 /*******************************************************************************
183 * Calculate the joint states
184 *******************************************************************************/
186 {
187  joint_states_.position[LEFT] = last_position_[LEFT];
189  joint_states_.velocity[LEFT] = last_velocity_[LEFT];
191 }
192 
193 /*******************************************************************************
194 * Calculate the TF
195 *******************************************************************************/
196 void Turtlebot3Fake::updateTF(geometry_msgs::TransformStamped& odom_tf)
197 {
198  odom_tf.header = odom_.header;
199  odom_tf.child_frame_id = odom_.child_frame_id;
200  odom_tf.transform.translation.x = odom_.pose.pose.position.x;
201  odom_tf.transform.translation.y = odom_.pose.pose.position.y;
202  odom_tf.transform.translation.z = odom_.pose.pose.position.z;
203  odom_tf.transform.rotation = odom_.pose.pose.orientation;
204 }
205 
206 /*******************************************************************************
207 * Update function
208 *******************************************************************************/
210 {
211  ros::Time time_now = ros::Time::now();
212  ros::Duration step_time = time_now - prev_update_time_;
213  prev_update_time_ = time_now;
214 
215  // zero-ing after timeout
216  if((time_now - last_cmd_vel_time_).toSec() > cmd_vel_timeout_)
217  {
218  wheel_speed_cmd_[LEFT] = 0.0;
219  wheel_speed_cmd_[RIGHT] = 0.0;
220  }
221 
222  // odom
223  updateOdometry(step_time);
224  odom_.header.stamp = time_now;
226 
227  // joint_states
228  updateJoint();
229  joint_states_.header.stamp = time_now;
231 
232  // tf
233  geometry_msgs::TransformStamped odom_tf;
234  updateTF(odom_tf);
236 
237  return true;
238 }
239 
240 /*******************************************************************************
241 * Main function
242 *******************************************************************************/
243 int main(int argc, char* argv[])
244 {
245  ros::init(argc, argv, "turtlebot3_fake_node");
246  Turtlebot3Fake tb3fake;
247 
248  ros::Rate loop_rate(30);
249 
250  while (ros::ok())
251  {
252  tb3fake.update();
253  ros::spinOnce();
254  loop_rate.sleep();
255  }
256 
257  return 0;
258 }
std::string joint_states_name_[2]
ros::Publisher joint_states_pub_
ros::Subscriber cmd_vel_sub_
float odom_pose_[3]
ros::NodeHandle nh_
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
double last_velocity_[2]
sensor_msgs::JointState joint_states_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ros::Time last_cmd_vel_time_
double wheel_speed_cmd_[2]
float odom_vel_[3]
void commandVelocityCallback(const geometry_msgs::TwistConstPtr cmd_vel_msg)
#define LEFT
double wheel_seperation_
bool param(const std::string &param_name, T &param_val, const T &default_val) const
int main(int argc, char *argv[])
ROSCPP_DECL bool ok()
void sendTransform(const StampedTransform &transform)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define RIGHT
void updateJoint(void)
bool sleep()
ros::Time prev_update_time_
bool updateOdometry(ros::Duration diff_time)
TFSIMD_FORCE_INLINE const tfScalar & w() const
static geometry_msgs::Quaternion createQuaternionMsgFromYaw(double yaw)
#define WHEEL_RADIUS
tf::TransformBroadcaster tf_broadcaster_
double cmd_vel_timeout_
double goal_angular_velocity_
static Time now()
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
void updateTF(geometry_msgs::TransformStamped &odom_tf)
#define ROS_ASSERT(cond)
ros::Publisher odom_pub_
nav_msgs::Odometry odom_
ROSCPP_DECL void spinOnce()
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
double last_position_[2]
double goal_linear_velocity_


turtlebot3_fake
Author(s): Pyo , Darby Lim
autogenerated on Sat Jan 16 2021 03:56:02