MobilityBasePlugin.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2014-2017, Dataspeed Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Dataspeed Inc. nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
36 
37 namespace gazebo
38 {
39 
41  nh_(NULL), spinner_thread_(NULL), tf_broadcaster_(NULL), first_update_(true), fast_(true)
42 {
43  omni_a_ = 1.0 / WHEEL_RADIUS;
44  omni_b_ = 1.0 / WHEEL_RADIUS;
46  frame_id_ = "/base_footprint";
47  mode_ = mobility_base_core_msgs::Mode::MODE_DISABLED;
48 }
50 {
51  if (nh_) {
52  delete nh_;
53  }
54  if (spinner_thread_) {
55  delete spinner_thread_;
56  }
57 }
59 {
60  nh_->shutdown();
61  spinner_thread_->join();
62 }
63 
64 void MobilityBasePlugin::omniFromCartesian(double vx, double vy, double wz, double w[4]) const {
65  w[0] = omni_a_ * vx - omni_b_ * vy - omni_c_ * wz;
66  w[1] = omni_a_ * vx + omni_b_ * vy + omni_c_ * wz;
67  w[2] = omni_a_ * vx + omni_b_ * vy - omni_c_ * wz;
68  w[3] = omni_a_ * vx - omni_b_ * vy + omni_c_ * wz;
69 }
70 
71 // generated with MATLAB omni_invert(9.842519685, 9.842519685, 5.836279527)
72 //const double slip_inv_[3][4] = {
73 // {+0.0254000000,+0.0254000000,+0.0254000000,+0.0254000000,},
74 // {-0.0254000000,+0.0254000000,+0.0254000000,-0.0254000000,},
75 // {-0.0428355083,+0.0428355083,-0.0428355083,+0.0428355083,},
76 //};
77 
78 void MobilityBasePlugin::omniToCartesian(const double w[4], double *vx, double *vy, double *wz) const {
79 // *vx = slip_inv_[0][0] * w[0] + slip_inv_[0][1] * w[1] + slip_inv_[0][2] * w[2] + slip_inv_[0][3] * w[3];
80 // *vy = slip_inv_[1][0] * w[0] + slip_inv_[1][1] * w[1] + slip_inv_[1][2] * w[2] + slip_inv_[1][3] * w[3];
81 // *wz = slip_inv_[2][0] * w[0] + slip_inv_[2][1] * w[1] + slip_inv_[2][2] * w[2] + slip_inv_[2][3] * w[3];
82 }
83 
84 void MobilityBasePlugin::Load(physics::ModelPtr parent, sdf::ElementPtr sdf)
85 {
86  first_update_ = true;
87 
88  // Store the pointer to the model and world
89  model_ = parent;
90  world_ = model_->GetWorld();
91 
92  // Get then name of the parent model
93  std::string model_name = sdf->GetParent()->Get<std::string>("name");
94  gzdbg << "MobilityBasePlugin loaded for model '" << model_name << "'\n";
95 
96  // Get parameters
97  if (sdf->HasElement("fast")) {
98  std::string comp = "true";
99  fast_ = comp.compare(sdf->GetElement("fast")->Get<std::string>()) ? false : true;
100  }
101  if (sdf->HasElement("parent_frame_id")) {
102  parent_frame_id_ = sdf->GetElement("parent_frame_id")->Get<std::string>();
103  if (sdf->HasElement("child_frame_id")) {
104  child_frame_id_ = sdf->GetElement("child_frame_id")->Get<std::string>();
105  } else {
107  }
109  }
110 
111  // Get the pointer to the base_link
112  link_base_footprint_ = model_->GetLink("base_footprint");
113 
114  joint_state_wheels_.name.push_back("wheel_fl");
115  joint_state_wheels_.name.push_back("wheel_fr");
116  joint_state_wheels_.name.push_back("wheel_rl");
117  joint_state_wheels_.name.push_back("wheel_rr");
118 
119  // Setup joints
120  for (unsigned int i = 0; i < NUM_WHEELS; i++) {
121  // Wheel joint
122  const std::string &wheel = joint_state_wheels_.name[i];
123  joint_wheels_[i] = parent->GetJoint(wheel);
124  if (joint_wheels_[i]) {
125  joint_wheels_[i]->SetDamping(0, 0.1);
126  joint_state_wheels_.position.push_back(0);
127  joint_state_wheels_.velocity.push_back(0);
128  joint_state_wheels_.effort.push_back(0);
129  } else {
130  gzerr << "Failed to find joint '" << wheel << "' in the model\n";
131  return;
132  }
133  if (!fast_) {
134  // Roller joints
135  for (unsigned int j = 0; j < NUM_ROLLERS; j++) {
136  std::stringstream ss;
137  ss << wheel << "_roller_" << j;
138  std::string roller = ss.str();
139  joint_rollers_[i][j] = parent->GetJoint(roller);
140  if (joint_rollers_[i][j]) {
141  joint_rollers_[i][j]->SetDamping(0, 0.0005);
142  joint_state_rollers_.name.push_back(roller);
143  joint_state_rollers_.position.push_back(0);
144  joint_state_rollers_.velocity.push_back(0);
145  joint_state_rollers_.effort.push_back(0);
146  } else {
147  gzerr << "Failed to find joint '" << roller << "' in the model\n";
148  return;
149  }
150  }
151  }
152  }
153 
154  // Initialize the ROS node
155  int argc = 0;
156  char** argv = NULL;
158  nh_ = new ros::NodeHandle("/mobility_base");
159 
160  // Set up Publishers
161  pub_imu_data_ = nh_->advertise<sensor_msgs::Imu>("imu/data_raw", 10, false);
162  pub_imu_mag_ = nh_->advertise<sensor_msgs::MagneticField>("imu/mag", 10, false);
163  pub_imu_is_calibrated_ = nh_->advertise<std_msgs::Bool>("imu/is_calibrated", 1, true);
164  pub_twist_ = nh_->advertise<geometry_msgs::TwistStamped>("twist", 10, false);
165  pub_wrench_ = nh_->advertise<geometry_msgs::WrenchStamped>("wrench", 10, false);
166  pub_joint_states_ = nh_->advertise<sensor_msgs::JointState>("joint_states", 10, false);
167  pub_joystick_ = nh_->advertise<geometry_msgs::TwistStamped>("joystick", 10, false);
168  pub_bumper_states_ = nh_->advertise<mobility_base_core_msgs::BumperState>("bumper_states", 10, true);
169  pub_mode_ = nh_->advertise<mobility_base_core_msgs::Mode>("mode", 1, true);
170 
171  // Set up Publisher Queues
173  pmq_imu_data_ = pmq_.addPub<sensor_msgs::Imu>();
174  pmq_imu_mag_ = pmq_.addPub<sensor_msgs::MagneticField>();
175  pmq_imu_is_calibrated_ = pmq_.addPub<std_msgs::Bool>();
176  pmq_twist_ = pmq_.addPub<geometry_msgs::TwistStamped>();
177  pmq_wrench_ = pmq_.addPub<geometry_msgs::WrenchStamped>();
178  pmq_joint_states_ = pmq_.addPub<sensor_msgs::JointState>();
179  pmq_joystick_ = pmq_.addPub<geometry_msgs::TwistStamped>();
180  pmq_bumper_states_ = pmq_.addPub<mobility_base_core_msgs::BumperState>();
181  pmq_mode_ = pmq_.addPub<mobility_base_core_msgs::Mode>();
182 
183  // Set up Subscribers
184  sub_cmd_vel_ = nh_->subscribe("cmd_vel", 1, &MobilityBasePlugin::recvCmdVel, this);
186 
187  // Publish latched topics 'mode' and 'imu/is_calibrated'
189  std_msgs::Bool msg;
190  msg.data = true;
191  pmq_imu_is_calibrated_->push(msg, pub_imu_is_calibrated_);
192 
193  // Listen to the update event. This event is broadcast every simulation iteration.
194  spinner_thread_ = new boost::thread(boost::bind( &MobilityBasePlugin::spin, this));
195  update_connection_ = event::Events::ConnectWorldUpdateBegin(boost::bind(&MobilityBasePlugin::UpdateChild, this, _1));
196 }
197 
198 // Called by the world update start event
199 void MobilityBasePlugin::UpdateChild(const common::UpdateInfo & _info)
200 {
201  const common::Time gstamp = world_->GetSimTime();
202  const ros::Time rstamp(gstamp.sec, gstamp.nsec);
203  const double ts = (gstamp - previous_stamp_).Double();
204 
205  // Header for all messages
206  std_msgs::Header header;
207  header.stamp = rstamp;
208  header.frame_id = frame_id_;
209 
210  // Grab model states from Gazebo
211  math::Vector3 linear_vel;
212  math::Vector3 angular_vel;
213  math::Vector3 linear_accel;
214  math::Vector3 angular_pos;
215  math::Quaternion orientation;
216  math::Vector3 position;
217 
218  linear_vel = model_->GetRelativeLinearVel();
219  angular_vel = model_->GetRelativeAngularVel();
220  linear_accel = model_->GetRelativeLinearAccel();
221  angular_pos = model_->GetWorldPose().rot.GetAsEuler();
222  orientation = model_->GetWorldPose().rot;
223  position = model_->GetWorldPose().pos;
224 
225  const math::Vector3 fb_vel(linear_vel.x, linear_vel.y, angular_vel.z);
226 
227  // Command wheel velocity and torque to meet robot velocity request
228  if (first_update_) {
229  stamp_vehicle_ = gstamp;
230  stamp_imu_ = gstamp;
231  stamp_joystick_ = gstamp;
232  stamp_bumpers_ = gstamp;
233  stamp_mode_ = gstamp;
234  cmd_vel_history_ = math::Vector3::Zero;
235 
236  } else {
237  // Select command source
238  math::Vector3 cmd = math::Vector3::Zero;
239  mobility_base_core_msgs::Mode::_mode_type mode = mobility_base_core_msgs::Mode::MODE_TIMEOUT;
240  {
241  boost::lock_guard<boost::mutex> lock1(cmd_vel_mutex_);
242  boost::lock_guard<boost::mutex> lock2(cmd_vel_raw_mutex_);
244  if (gstamp - cmd_vel_stamp_ < common::Time(CMD_TIMEOUT)) {
245  cmd = cmd_vel_;
246  mode = mobility_base_core_msgs::Mode::MODE_VELOCITY;
247  }
248  } else {
249  if (gstamp - cmd_vel_raw_stamp_ < common::Time(CMD_TIMEOUT)) {
250  cmd = cmd_vel_raw_;
251  mode = mobility_base_core_msgs::Mode::MODE_VELOCITY_RAW;
252  }
253  }
254  }
255 
256  // Select acceleration limits
257  math::Vector3 accel_limit;
258  switch (mode) {
259  case mobility_base_core_msgs::Mode::MODE_VELOCITY:
260  accel_limit.x = ACCEL_LIMIT_SLOW_VXY;
261  accel_limit.y = ACCEL_LIMIT_SLOW_VXY;
262  accel_limit.z = ACCEL_LIMIT_SLOW_WZ;
263  break;
264  case mobility_base_core_msgs::Mode::MODE_VELOCITY_RAW:
265  case mobility_base_core_msgs::Mode::MODE_TIMEOUT:
266  default:
267  accel_limit.x = ACCEL_LIMIT_FAST_VXY;
268  accel_limit.y = ACCEL_LIMIT_FAST_VXY;
269  accel_limit.z = ACCEL_LIMIT_FAST_WZ;
270  break;
271  }
272 
273  // Initialize feedback for velocity change calculation
274  if (mode != mode_) {
275  cmd_vel_history_ = fb_vel;
276  }
277 
278  // Limit change in velocity from previous command
279  math::Vector3 temp;
280  temp.x = limitDelta(cmd.x, cmd_vel_history_.x, accel_limit.x * ts); // m/s^2
281  temp.y = limitDelta(cmd.y, cmd_vel_history_.y, accel_limit.y * ts); // m/s^2
282  temp.z = limitDelta(cmd.z, cmd_vel_history_.z, accel_limit.z * ts); // rad/s^2
283 
284  // Limit change in velocity from feedback
285  temp.x = limitDelta(temp.x, fb_vel.x, ACCEL_INSTANT_VXY); // m/s
286  temp.y = limitDelta(temp.y, fb_vel.y, ACCEL_INSTANT_VXY); // m/s
287  temp.z = limitDelta(temp.z, fb_vel.z, ACCEL_INSTANT_WZ); // rad/s
288 
289  // Compute motor velocity commands
290  double speed[4];
291  omniFromCartesian(temp.x, temp.y, temp.z, speed);
292  if (omniSaturate(RADIANS_PER_SECOND_MAX, speed)) {
293  cmd_vel_history_ = fb_vel;
294  } else {
295  cmd_vel_history_ = temp;
296  }
297 
298  if (fast_) {
299  // Apply force and torque to base_footprint to control mobility_base
300  math::Vector3 linear_vel = orientation.RotateVector(math::Vector3(temp.x, temp.y, 0.0));
301  math::Vector3 linear_vel_orig = link_base_footprint_->GetRelativeLinearVel();
302  math::Vector3 angular_vel_orig = link_base_footprint_->GetRelativeAngularVel();
303  link_base_footprint_->SetLinearVel(math::Vector3(GAIN_X * linear_vel.x, GAIN_Y * linear_vel.y, linear_vel_orig.z + linear_vel.z));
304  link_base_footprint_->SetAngularVel(math::Vector3(angular_vel_orig.x, angular_vel_orig.y, GAIN_Z * temp.z));
305  }
306 
307  // Command the wheel motors
308  for (unsigned int i = 0; i < NUM_WHEELS; i++) {
309  joint_wheels_[i]->SetVelocity(0, speed[i]);
310 #if GAZEBO_MAJOR_VERSION >= 7
311  joint_wheels_[i]->SetEffortLimit(0, TORQUE_MAX_GLOBAL);
312 #else
313  joint_wheels_[i]->SetMaxForce(0, TORQUE_MAX_GLOBAL);
314 #endif
315  }
316 
317  // Publish vehicle feedback
318  if (gstamp - stamp_vehicle_ >= common::Time(1.0 / PUB_FREQ_VEHICLE)) {
319  stamp_vehicle_ += common::Time(1.0 / PUB_FREQ_VEHICLE);
320 
321  // Publish twist
322  geometry_msgs::TwistStamped msg_twist;
323  msg_twist.header = header;
324  msg_twist.twist.linear.x = linear_vel.x;
325  msg_twist.twist.linear.y = linear_vel.y;
326  msg_twist.twist.linear.z = linear_vel.z;
327  msg_twist.twist.angular.x = angular_vel.x;
328  msg_twist.twist.angular.y = angular_vel.y;
329  msg_twist.twist.angular.z = angular_vel.z;
330  pmq_twist_->push(msg_twist, pub_twist_);
331 
332  // Publish wrench
333  geometry_msgs::WrenchStamped msg_wrench;
334  msg_wrench.header = header;
335  msg_wrench.wrench.force.x = 0.0;
336  msg_wrench.wrench.force.y = 0.0;
337  msg_wrench.wrench.torque.z = 0.0;
338  pmq_wrench_->push(msg_wrench, pub_wrench_);
339 
340  // Publish joint_states
341  joint_state_wheels_.header = header;
342  if (!fast_)
343  joint_state_rollers_.header = header;
344  for (unsigned int i = 0; i < NUM_WHEELS; i++) {
345  joint_state_wheels_.position[i] = joint_wheels_[i]->GetAngle(0).Radian();
346  joint_state_wheels_.velocity[i] = joint_wheels_[i]->GetVelocity(0);
347 
348  if (!fast_) {
349  for (unsigned int j = 0; j < NUM_ROLLERS; j++) {
350  joint_state_rollers_.position[i * NUM_ROLLERS + j] = joint_rollers_[i][j]->GetAngle(0).Radian();
351  joint_state_rollers_.velocity[i * NUM_ROLLERS + j] = joint_rollers_[i][j]->GetVelocity(0);
352  }
353  }
354  }
356  if (!fast_)
358 
359  // Optionally publish tf transform
360  if (tf_broadcaster_) {
361  geometry_msgs::TransformStamped transform;
362  transform.header.stamp = rstamp;
363  transform.header.frame_id = parent_frame_id_;
364  transform.child_frame_id = child_frame_id_;
365  transform.transform.translation.x = position.x;
366  transform.transform.translation.y = position.y;
367  transform.transform.translation.z = position.z;
368  transform.transform.rotation.w = orientation.w;
369  transform.transform.rotation.x = orientation.x;
370  transform.transform.rotation.y = orientation.y;
371  transform.transform.rotation.z = orientation.z;
372  tf_broadcaster_->sendTransform(transform);
373  }
374  }
375 
376  // Publish imu feedback
377  if (gstamp - stamp_imu_ >= common::Time(1.0 / PUB_FREQ_IMU)) {
378  stamp_imu_ += common::Time(1.0 / PUB_FREQ_IMU);
379 
380  // Publish imu_data_
381  sensor_msgs::Imu msg_imu;
382  msg_imu.header = header;
383  msg_imu.linear_acceleration.x = linear_accel.x;
384  msg_imu.linear_acceleration.y = linear_accel.y;
385  msg_imu.linear_acceleration.z = linear_accel.z;
386  msg_imu.orientation_covariance[0] = -1;
387  msg_imu.angular_velocity.x = angular_vel.x;
388  msg_imu.angular_velocity.y = angular_vel.y;
389  msg_imu.angular_velocity.z = angular_vel.z;
390  msg_imu.angular_velocity_covariance[0] = -1;
391  pmq_imu_data_->push(msg_imu, pub_imu_data_);
392 
393  sensor_msgs::MagneticField msg_mag;
394  msg_mag.header = header;
395  msg_mag.magnetic_field.x = 0.0;
396  msg_mag.magnetic_field.y = 0.0;
397  msg_mag.magnetic_field.z = 0.0;
398  msg_mag.magnetic_field_covariance[0] = -1;
399  pmq_imu_mag_->push(msg_mag, pub_imu_mag_);
400  }
401 
402  // Publish joystick feedback
403  if (gstamp - stamp_joystick_ >= common::Time(1.0 / PUB_FREQ_JOYSTICK)) {
404  stamp_joystick_ += common::Time(1.0 / PUB_FREQ_JOYSTICK);
405  geometry_msgs::TwistStamped msg;
406  msg.header = header;
408  }
409 
410  // Publish bumper_states feedback
411  if (gstamp - stamp_bumpers_ >= common::Time(1.0 / PUB_FREQ_BUMPERS)) {
412  stamp_bumpers_ += common::Time(1.0 / PUB_FREQ_BUMPERS);
413  mobility_base_core_msgs::BumperState msg;
414  msg.front_left = 0;
415  msg.front_right = 0;
416  msg.rear_left = 0;
417  msg.rear_right = 0;
419  }
420 
421  // Publish mode feedback
422  if (mode != mode_) {
423  stamp_mode_ = gstamp;
424  publishMode(rstamp);
425  } else if (gstamp - stamp_mode_ >= common::Time(1.0 / PUB_FREQ_MODE)) {
426  stamp_mode_ += common::Time(1.0 / PUB_FREQ_MODE);
427  publishMode(rstamp);
428  }
429 
430  mode_ = mode;
431  }
432 
433  previous_stamp_ = gstamp;
434  first_update_ = false;
435 }
436 
437 void MobilityBasePlugin::recvCmdVel(const geometry_msgs::Twist::ConstPtr& msg)
438 {
439  boost::lock_guard<boost::mutex> lock(cmd_vel_mutex_);
440  cmd_vel_stamp_ = world_->GetSimTime();
441  cmd_vel_.x = msg->linear.x;
442  cmd_vel_.y = msg->linear.y;
443  cmd_vel_.z = msg->angular.z;
444 }
445 
446 void MobilityBasePlugin::recvCmdVelRaw(const geometry_msgs::Twist::ConstPtr& msg)
447 {
448  boost::lock_guard<boost::mutex> lock(cmd_vel_raw_mutex_);
449  cmd_vel_raw_stamp_ = world_->GetSimTime();
450  cmd_vel_raw_.x = msg->linear.x;
451  cmd_vel_raw_.y = msg->linear.y;
452  cmd_vel_raw_.z = msg->angular.z;
453 }
454 
456 {
457  mobility_base_core_msgs::Mode msg;
458  msg.header.frame_id = frame_id_;
459  msg.header.stamp = stamp;
460  msg.mode = mode_;
461  pmq_mode_->push(msg, pub_mode_);
462 }
463 
465 {
466  while (ros::ok()) {
467  ros::spinOnce();
468  }
469 }
470 
471 // Register this plugin with the simulator
473 }
static _CONST double PUB_FREQ_BUMPERS
msg
void push(T &msg, ros::Publisher &pub)
void recvCmdVel(const geometry_msgs::Twist::ConstPtr &msg)
physics::JointPtr joint_wheels_[NUM_WHEELS]
static _CONST double GAIN_X
physics::JointPtr joint_rollers_[NUM_WHEELS][NUM_ROLLERS]
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
string cmd
PubQueue< geometry_msgs::TwistStamped >::Ptr pmq_joystick_
static _CONST unsigned int NUM_ROLLERS
void recvCmdVelRaw(const geometry_msgs::Twist::ConstPtr &msg)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
static _CONST double ACCEL_INSTANT_VXY
void Load(physics::ModelPtr _parent, sdf::ElementPtr sdf)
static _CONST double GAIN_Y
static _CONST double ACCEL_LIMIT_FAST_WZ
static _CONST double ACCEL_INSTANT_WZ
event::ConnectionPtr update_connection_
static _CONST double PUB_FREQ_JOYSTICK
PubQueue< std_msgs::Bool >::Ptr pmq_imu_is_calibrated_
physics::LinkPtr link_base_footprint_
static _CONST double ACCEL_LIMIT_SLOW_WZ
static _CONST double ACCEL_LIMIT_SLOW_VXY
static _CONST double ACCEL_LIMIT_FAST_VXY
static bool omniSaturate(double limit, double speeds[4])
static _CONST double CMD_TIMEOUT
ROSCPP_DECL bool ok()
void omniFromCartesian(double vx, double vy, double wz, double w[4]) const
void sendTransform(const StampedTransform &transform)
PubQueue< sensor_msgs::MagneticField >::Ptr pmq_imu_mag_
static _CONST double WHEEL_RADIUS
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
boost::shared_ptr< PubQueue< T > > addPub()
sensor_msgs::JointState joint_state_rollers_
static _CONST double PUB_FREQ_IMU
PubQueue< mobility_base_core_msgs::BumperState >::Ptr pmq_bumper_states_
PubQueue< sensor_msgs::Imu >::Ptr pmq_imu_data_
PubQueue< sensor_msgs::JointState >::Ptr pmq_joint_states_
void omniToCartesian(const double w[4], double *vx, double *vy, double *wz) const
static _CONST double TORQUE_MAX_GLOBAL
static _CONST double WHEEL_BASE_LENGTH
static _CONST double PUB_FREQ_MODE
static _CONST double GAIN_Z
PubQueue< geometry_msgs::TwistStamped >::Ptr pmq_twist_
static _CONST unsigned int NUM_WHEELS
void startServiceThread()
GZ_REGISTER_MODEL_PLUGIN(GazeboRosP3D)
static _CONST double WHEEL_BASE_WIDTH
mobility_base_core_msgs::Mode::_mode_type mode_
ROSCPP_DECL void spinOnce()
virtual void UpdateChild(const common::UpdateInfo &_info)
void publishMode(const ros::Time &stamp)
tf::TransformBroadcaster * tf_broadcaster_
sensor_msgs::JointState joint_state_wheels_
PubQueue< geometry_msgs::WrenchStamped >::Ptr pmq_wrench_
static _CONST double RADIANS_PER_SECOND_MAX
PubQueue< mobility_base_core_msgs::Mode >::Ptr pmq_mode_
static _CONST double PUB_FREQ_VEHICLE
static double limitDelta(double input, double previous, double limit)


mobility_base_gazebo_plugins
Author(s): Dataspeed Inc.
autogenerated on Sun Oct 6 2019 03:32:29