clober_serial.cpp
Go to the documentation of this file.
2 
4  : port_("/dev/ttyUSB0"),
5  baudrate_(115200),
6  timeout_(50),
7  control_frequency_(50.0),
8  odom_frame_parent_("odom"),
9  odom_frame_child_("base_link"),
10  cmd_vel_timeout_(1.0),
11  odom_mode_(0)
12 {
13 
14  ros::NodeHandle private_nh("~");
15  ros::NodeHandle nh;
16 
17  private_nh.getParam("port", port_);
18  private_nh.getParam("baud", baudrate_);
19  private_nh.getParam("timeout", timeout_);
20  private_nh.getParam("control_frequency", control_frequency_);
21  private_nh.getParam("odom_frame_parent", odom_frame_parent_);
22  private_nh.getParam("odom_frame_child", odom_frame_child_);
23  private_nh.getParam("cmd_vel_timeout", cmd_vel_timeout_);
24  private_nh.getParam("mode", odom_mode_);
25 
26 
27  private_nh.getParam("wheel_separation", config_.WIDTH);
28  private_nh.getParam("wheel_radius", config_.WheelRadius);
29  private_nh.getParam("wheel_max_speed_mps", config_.MAX_SPEED);
30  private_nh.getParam("wheel_max_rpm", config_.MAX_RPM);
31  private_nh.getParam("encoder_ppr", config_.encoder.ppr);
32 
34 
35  // initalize
36  SetValues();
37 
38  try
39  {
40  serial_ = std::make_unique<serial::Serial>(port_, baudrate_);
42  serial_->setTimeout(to);
43  }
44  catch (const std::exception &e)
45  {
46  cout << "connection failed" << endl;
47  }
48 
49  cout << "Connected to serial : " << port_ << " with baudrate " << baudrate_ << endl;
50  restartScript();
51 
52  odom_pub_ = nh.advertise<nav_msgs::Odometry>("odom", 1);
53  feedback_pub_ = nh.advertise<clober_msgs::Feedback>("feedback", 1);
54  cmd_vel_sub_ = nh.subscribe<geometry_msgs::Twist>("cmd_vel", 1, bind(&CloberSerial::cmd_vel_callback, this, _1));
55 
56  readThread_ = std::make_shared<thread>(bind(&CloberSerial::read_serial, this, 20));
57  publishThread_ = std::make_shared<thread>(bind(&CloberSerial::publish_loop, this, control_frequency_));
58 }
59 
61 {
62  readThread_->detach();
63  if (readThread_->joinable())
64  {
65  readThread_->join();
66  }
67 }
68 
70 {
73  trigger_ = false;
74  posX_ = 0.0;
75  posY_ = 0.0;
76  heading_ = 0.0;
77 }
78 
79 void CloberSerial::cmd_vel_callback(const geometry_msgs::Twist::ConstPtr &msg)
80 {
81  motor_cmd_.linearVel = msg->linear.x;
82  motor_cmd_.angularVel = msg->angular.z;
84 
85  // rpmValue_+=16;
86  sendHeardBeat();
88 
89 }
90 
92 {
93  while (ros::ok())
94  {
95  parse();
96  // std::this_thread::sleep_for(std::chrono::milliseconds(ms));
97  }
98 }
99 
101 {
102  string msg = serial_->readline(max_line_length, eol);
103  // cout <<msg<<endl;
104 
105  if (msg.size() > 2)
106  {
107  if (msg[0] == 'F' && msg[2] == ':')
108  {
109  try
110  {
111  size_t index = boost::lexical_cast<size_t>(msg[1]);
112 
113  vector<string> feedbacks;
114  boost::split(feedbacks, msg, boost::algorithm::is_any_of(":"));
115 
116  // cout <<msg<<endl;
117 
118  // // The status of the controller
119  // config_.controller_state.battery_voltage = (boost::lexical_cast<double>(feedbacks[1]) / 10.0) + 0.4;
120  // config_.controller_state.temperature = boost::lexical_cast<double>(feedbacks[2]);
121 
122  // if (boost::lexical_cast<int>(feedbacks[3]) == 0){
123  // config_.controller_state.emergency_stop = true;
124  // } else {
125  // config_.controller_state.emergency_stop = false;
126  // }
127 
128  // faultFlags(boost::lexical_cast<uint16_t>(feedbacks[4]));
129 
130  if (feedbacks.size() > 8)
131  {
132  config_.left_motor.rpm = boost::lexical_cast<float>(feedbacks[5]);
133  config_.left_motor.speed = utils_.toVelocity(boost::lexical_cast<float>(feedbacks[5]));
134 
135  config_.right_motor.rpm = boost::lexical_cast<float>(feedbacks[6]);
136  config_.right_motor.speed = utils_.toVelocity(boost::lexical_cast<float>(feedbacks[6]));
137 
138  config_.left_motor.position_rad += utils_.toRad(boost::lexical_cast<float>(feedbacks[7]), config_.encoder.ppr);
140 
141  config_.right_motor.position_rad += utils_.toRad(boost::lexical_cast<float>(feedbacks[8]), config_.encoder.ppr);
143 
144  config_.left_motor.current = boost::lexical_cast<double>(feedbacks[9]) / 10.0;
145  config_.right_motor.current = boost::lexical_cast<double>(feedbacks[10]) / 10.0;
146 
149 
150  // rad/s -> m/s
151  double l_speed = config_.left_motor.speed * config_.WheelRadius;
152  double r_speed = config_.right_motor.speed * config_.WheelRadius;
153 
154  toVW(l_speed, r_speed);
155 
156  switch (odom_mode_)
157  {
158  case 0:
159  updatePose();
160  break;
161 
162  case 1:
163  updatePose(l_speed, r_speed);
164  break;
165 
166  case 2:
167  updatePose(dl, dr);
168  break;
169 
170  default:
171  updatePose();
172  break;
173  }
174 
177  }
178  }
179  catch (boost::bad_lexical_cast &e)
180  {
181  }
182  }
183  else if (msg[0] == 'I' && msg[1] == 'O' && msg[2] == ':')
184  {
185  try
186  {
187  vector<string> io;
188  boost::split(io, msg, boost::algorithm::is_any_of(":"));
189 
190  config_.controller_state.charging_voltage = boost::lexical_cast<double>(io[1]) / 1000.0 * 6.0;
191  config_.controller_state.current_12v = boost::lexical_cast<double>(io[2]) / 1000.0 * 0.0048;
192  config_.controller_state.current_24v = boost::lexical_cast<double>(io[3]) / 1000.0 * 0.0048;
193  }
194  catch (boost::bad_lexical_cast& e)
195  {
196  }
197  }
198  }
199 }
200 
201 void CloberSerial::faultFlags(const uint16_t flags)
202 {
204  if (bitset<16>(flags)[0] == 1)
205  config_.controller_state.fault_flags.push_back("Overheat");
206  if (bitset<16>(flags)[1] == 1)
207  config_.controller_state.fault_flags.push_back("Overvoltage");
208  if (bitset<16>(flags)[2] == 1)
209  config_.controller_state.fault_flags.push_back("Undervoltage");
210  if (bitset<16>(flags)[3] == 1)
211  config_.controller_state.fault_flags.push_back("Short circuit");
212  if (bitset<16>(flags)[4] == 1)
213  config_.controller_state.fault_flags.push_back("Emergency stop");
214  if (bitset<16>(flags)[5] == 1)
215  config_.controller_state.fault_flags.push_back("Motor/Sensor setup fault");
216  if (bitset<16>(flags)[6] == 1)
217  config_.controller_state.fault_flags.push_back("MOSFET failure");
218  if (bitset<16>(flags)[7] == 1)
219  config_.controller_state.fault_flags.push_back("Default configuration loaded at startup");
220 }
221 
222 void CloberSerial::toVW(float l_speed, float r_speed)
223 {
224  linearVel_ = (l_speed + r_speed) / 2;
225  angularVel_ = (r_speed - l_speed) / config_.WIDTH;
226 
227  // cout << "Current Velocity : linear : " << linearVel_ << ", angular : " << angularVel_ << endl;
228 }
229 
230 pair<float, float> CloberSerial::toWheelSpeed(float v, float w)
231 {
232  // v, w -> wheel angular speed (rad/s)
233  float r_speed = (v + (config_.WIDTH * w / 2)) / config_.WheelRadius;
234  float l_speed = (v - (config_.WIDTH * w / 2)) / config_.WheelRadius;
235 
236  return make_pair(l_speed, r_speed);
237 }
238 
239 float CloberSerial::limitMaxSpeed(float speed)
240 {
241  // wheel angular max speed (rad/s)
242  float max = config_.MAX_SPEED / config_.WheelRadius;
243  if (abs(speed) > max)
244  {
245  if (speed > 0)
246  {
247  return max;
248  }
249  else
250  {
251  return -max;
252  }
253  }
254  else
255  {
256  return speed;
257  }
258 }
259 
261 {
262  ros::Time now = ros::Time::now();
263 
264  if (!trigger_)
265  {
266  timestamp_ = now;
267  trigger_ = true;
268  return;
269  }
270 
271  double dT = now.toSec() - timestamp_.toSec();
272  timestamp_ = now;
273 
274  float x = linearVel_ * dT * cos(heading_);
275  float y = linearVel_ * dT * sin(heading_);
276  float theta = angularVel_ * dT;
277 
278  posX_ += x;
279  posY_ += y;
280  heading_ += theta;
281 
282  // cout << "update pose x : " << posX_ << ", y : " << posY_ << ", heading : " << heading_ << endl << endl;
283 }
284 
285 void CloberSerial::updatePose(double dL, double dR)
286 {
287  ros::Time now = ros::Time::now();
288 
289  if (!trigger_)
290  {
291  timestamp_ = now;
292  trigger_ = true;
293  return;
294  }
295 
296  double dT = now.toSec() - timestamp_.toSec();
297  timestamp_ = now;
298 
299  double x = posX_;
300  double y = posY_;
301  float theta = heading_;
302 
303  float R = 0.0;
304  // if ((dR - dL) < 0.0001)
305  if ((dR - dL) == 0.0000 )
306  {
307  R = 0.0;
308  }
309  else
310  {
311  R = (config_.WIDTH / 2.0) * ((dL + dR) / (dR - dL));
312  }
313 
314  double Wdt;
315 
316  if ( odom_mode_ == 1 ){
317  double W = (dR - dL) / config_.WIDTH; // dR, dL 인자를 속도값으로 넘겼을 때, dT를 곱해서 계산
318  Wdt = W*dT;
319  }else if ( odom_mode_ == 2){
320  Wdt = (dR - dL) / config_.WIDTH; // dR, dL 인자를 거리값으로 넘겼을 때,
321  }
322 
323  double ICCx = x - (R * sin(theta));
324  double ICCy = y + (R * cos(theta));
325 
326  cout <<"ICCx : "<<ICCx <<" , ICCy : "<<ICCy <<endl;
327 
328 
329  posX_ = (cos(Wdt) * (x - ICCx)) - (sin(Wdt) * (y - ICCy)) + ICCx;
330  posY_ = (sin(Wdt) * (x - ICCx)) + (cos(Wdt) * (y - ICCy)) + ICCy;
331  heading_ = theta + Wdt;
332 
333  cout << "update pose x : " << posX_ << ", y : " << posY_ << ", heading : " << heading_ << endl << endl;
334 }
335 
337 {
338  int ms = 1000 * (float)1/hz;
339  cout << "publish loop hz : "<<hz <<", ms : "<<ms<<endl;
340  while (ros::ok())
341  {
342  publishOdom();
343  publishFeedback();
344  std::this_thread::sleep_for(std::chrono::milliseconds(ms));
345  }
346 }
347 
349 {
350  clober_msgs::Feedback feedback;
351 
352  ros::Time stamp_now = ros::Time::now();
353 
354  feedback.header.stamp = stamp_now;
355  feedback.controller_state.emergency_stop = config_.controller_state.emergency_stop;
356  feedback.controller_state.battery_voltage = config_.controller_state.battery_voltage;
357  feedback.controller_state.charging_voltage = config_.controller_state.charging_voltage;
358  feedback.controller_state.current_12v = config_.controller_state.current_12v;
359  feedback.controller_state.current_24v = config_.controller_state.current_24v;
360  feedback.controller_state.temperature = config_.controller_state.temperature;
361  feedback.controller_state.fault_flags = config_.controller_state.fault_flags;
362 
363  feedback.left_motor.position = config_.left_motor.position_rad;
364  feedback.right_motor.position = config_.right_motor.position_rad;
365  feedback.left_motor.velocity = config_.left_motor.rpm;
366  feedback.right_motor.velocity = config_.right_motor.rpm;
367  feedback.left_motor.current = config_.left_motor.current;
368  feedback.right_motor.current = config_.right_motor.current;
369 
370  feedback_pub_.publish(feedback);
371 }
372 
374 {
375  tf2::Quaternion q;
376  q.setRPY(0.0, 0.0, heading_);
377 
378  ros::Time stamp_now = ros::Time::now();
379 
380  nav_msgs::Odometry odom;
381  odom.header.frame_id = odom_frame_parent_;
382  odom.child_frame_id = odom_frame_child_;
383  odom.header.stamp = stamp_now;
384  odom.pose.pose.position.x = posX_;
385  odom.pose.pose.position.y = posY_;
386  odom.pose.pose.orientation.x = q.x();
387  odom.pose.pose.orientation.y = q.y();
388  odom.pose.pose.orientation.z = q.z();
389  odom.pose.pose.orientation.w = q.w();
390  odom.pose.covariance.fill(0.0);
391  odom.pose.covariance[0] = 1e-3;
392  odom.pose.covariance[7] = 1e-3;
393  odom.pose.covariance[14] = 1e6;
394  odom.pose.covariance[21] = 1e6;
395  odom.pose.covariance[28] = 1e6;
396  odom.pose.covariance[35] = 1e-3;
397 
398  odom.twist.twist.linear.x = linearVel_;
399  odom.twist.twist.angular.z = angularVel_;
400  odom.twist.covariance.fill(0.0);
401  odom.twist.covariance[0] = 1e-3;
402  odom.twist.covariance[7] = 1e-3;
403  odom.twist.covariance[14] = 1e6;
404  odom.twist.covariance[21] = 1e6;
405  odom.twist.covariance[28] = 1e6;
406  odom.twist.covariance[35] = 1e3;
407 
408  geometry_msgs::TransformStamped odom_tf;
409  odom_tf.header.stamp = stamp_now;
410  odom_tf.header.frame_id = odom_frame_parent_;
411  odom_tf.child_frame_id = odom_frame_child_;
412  odom_tf.transform.translation.x = posX_;
413  odom_tf.transform.translation.y = posY_;
414  odom_tf.transform.translation.z = 0;
415  odom_tf.transform.rotation = odom.pose.pose.orientation;
416  tf_broadcaster_.sendTransform(odom_tf);
417 
418  odom_pub_.publish(odom);
419 
420  // cout << "odom x : " << posX_ << ", y : " << posY_ << ", heading : " << heading_ << endl;
421 
422  // static int timeout_counter = 0;
423  // if( !cmd_vel_timeout_switch_){
424  // timeout_counter = 0;
425  // cmd_vel_timeout_switch_ = true;
426  // }else{
427  // if( timeout_counter > cmd_vel_timeout_*odom_freq_){
428  // motor_cmd_.linearVel = 0;
429  // motor_cmd_.angularVel = 0;
430  // timeout_counter = 0;
431  // }else{
432  // timeout_counter++;
433  // }
434  // }
435 
436  // on_motor_move(motor_cmd_);
437 }
438 
439 
441  stringstream msg;
442  msg << "!B 3 1" << "\r";
443  serial_->write(msg.str());
444 }
445 
446 
448  stringstream msg;
449  msg << "!R 2" << "\r";
450  serial_->write(msg.str());
451 }
452 
453 
455 {
456  pair<float, float> wheel_speed;
457 
458  wheel_speed = toWheelSpeed(cmd.linearVel, cmd.angularVel);
459  wheel_speed.first = limitMaxSpeed(wheel_speed.first);
460  wheel_speed.second = limitMaxSpeed(wheel_speed.second);
461 
462  pair<float, float> wheel_rpm;
463  wheel_rpm.first = utils_.toRPM(wheel_speed.first) * 1000 / config_.MAX_RPM;
464  wheel_rpm.second = utils_.toRPM(wheel_speed.second) * 1000 / config_.MAX_RPM;
465 
466  // cout <<"wheel first : "<< wheel_rpm.first <<", second : " << wheel_rpm.second << endl;
467 
468  if (abs(wheel_rpm.first) < 0.0001 && abs(wheel_rpm.second) < 0.0001)
469  {
470  sendStop(make_pair(0,1));
471  }else{
472  sendRPM(make_pair(0, 1), make_pair(wheel_rpm.first, wheel_rpm.second));
473  }
474 }
475 
476 void CloberSerial::sendRPM(pair<int, int> channel, pair<float, float> rpm)
477 {
478  stringstream msg;
479  msg << "!G " << channel.first + 1 << " " << rpm.first << "\r"
480  << "!G " << channel.second + 1 << " " << rpm.second << "\r";
481 
482  serial_->write(msg.str());
483  cout << "send rpm : " << msg.str() << endl;
484 }
485 
486 void CloberSerial::sendStop(pair<int,int> channel)
487 {
488  stringstream msg;
489  msg << "!MS " << channel.first + 1 << "\r" << "!MS " << channel.second + 1 << "\r";
490  serial_->write(msg.str());
491  cout << "stop : " << msg.str() << endl;
492 }
CloberSerial::SetValues
void SetValues()
Definition: clober_serial.cpp:69
CloberSerial::odom_freq_
double odom_freq_
Definition: clober_serial.hpp:128
Encoder::ppr
int ppr
Definition: clober_serial.hpp:33
VehicleConfig::encoder
Encoder encoder
Definition: clober_serial.hpp:60
CloberSerial::restartScript
void restartScript()
Definition: clober_serial.cpp:447
MotorState::position_rad
float position_rad
Definition: clober_serial.hpp:49
CloberSerial::sendRPM
void sendRPM(pair< int, int > channel, pair< float, float > rpm)
Definition: clober_serial.cpp:476
ControllerState::emergency_stop
bool emergency_stop
Definition: clober_serial.hpp:37
CloberSerial::odom_frame_parent_
std::string odom_frame_parent_
Definition: clober_serial.hpp:131
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
CloberSerial::serial_
std::shared_ptr< serial::Serial > serial_
Definition: clober_serial.hpp:108
CloberSerial::tf_broadcaster_
tf2_ros::TransformBroadcaster tf_broadcaster_
Definition: clober_serial.hpp:121
ControllerState::temperature
float temperature
Definition: clober_serial.hpp:38
CloberSerial::odom_frame_child_
std::string odom_frame_child_
Definition: clober_serial.hpp:132
CloberSerial::port_
std::string port_
Definition: clober_serial.hpp:109
CloberSerial::faultFlags
void faultFlags(const uint16_t flags)
Definition: clober_serial.cpp:201
CloberSerial::on_motor_move
void on_motor_move(MotorCommand cmd)
Definition: clober_serial.cpp:454
CloberSerial::control_frequency_
float control_frequency_
Definition: clober_serial.hpp:112
CloberSerial::parse
void parse()
Definition: clober_serial.cpp:100
CloberSerial::cmd_vel_sub_
ros::Subscriber cmd_vel_sub_
Definition: clober_serial.hpp:124
CloberSerial::odom_mode_
int odom_mode_
Definition: clober_serial.hpp:150
VehicleConfig::controller_state
ControllerState controller_state
Definition: clober_serial.hpp:63
CloberSerial::publish_loop
void publish_loop(int hz)
Definition: clober_serial.cpp:336
TimeBase< Time, Duration >::toSec
double toSec() const
CloberSerial::publishThread_
shared_ptr< thread > publishThread_
Definition: clober_serial.hpp:146
CloberSerial::utils_
CloberUtils utils_
Definition: clober_serial.hpp:148
CloberSerial::~CloberSerial
~CloberSerial()
Definition: clober_serial.cpp:60
eol
const string eol("\r")
CloberSerial::sendHeardBeat
void sendHeardBeat()
Definition: clober_serial.cpp:440
CloberSerial::feedback_pub_
ros::Publisher feedback_pub_
Definition: clober_serial.hpp:120
CloberSerial::toVW
void toVW(float l_speed, float r_speed)
Definition: clober_serial.cpp:222
CloberSerial::trigger_
bool trigger_
Definition: clober_serial.hpp:143
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
ros::ok
ROSCPP_DECL bool ok()
CloberSerial::posY_
double posY_
Definition: clober_serial.hpp:140
CloberSerial::publishFeedback
void publishFeedback()
Definition: clober_serial.cpp:348
CloberSerial::updatePose
void updatePose()
Definition: clober_serial.cpp:260
CloberSerial::timeout_
int timeout_
Definition: clober_serial.hpp:111
MotorState::rpm
float rpm
Definition: clober_serial.hpp:48
VehicleConfig::WheelRadius
float WheelRadius
Definition: clober_serial.hpp:57
max_line_length
const size_t max_line_length(128)
CloberSerial::motor_cmd_
MotorCommand motor_cmd_
Definition: clober_serial.hpp:126
CloberSerial::timestamp_
ros::Time timestamp_
Definition: clober_serial.hpp:106
MotorState::speed
float speed
Definition: clober_serial.hpp:47
CloberSerial::cmd_vel_timeout_
double cmd_vel_timeout_
Definition: clober_serial.hpp:129
CloberSerial::sendStop
void sendStop(pair< int, int > channel)
Definition: clober_serial.cpp:486
CloberUtils::toVelocity
float toVelocity(float rpm)
Definition: clober_utils.cpp:9
serial::Timeout::simpleTimeout
static Timeout simpleTimeout(uint32_t timeout)
Definition: serial.h:112
CloberSerial::CloberSerial
CloberSerial()
Definition: clober_serial.cpp:3
ControllerState::fault_flags
vector< string > fault_flags
Definition: clober_serial.hpp:43
CloberSerial::odom_pub_
ros::Publisher odom_pub_
Definition: clober_serial.hpp:119
CloberSerial::config_
VehicleConfig config_
Definition: clober_serial.hpp:134
ControllerState::battery_voltage
float battery_voltage
Definition: clober_serial.hpp:39
CloberSerial::cmd_vel_callback
void cmd_vel_callback(const geometry_msgs::Twist::ConstPtr &msg)
Definition: clober_serial.cpp:79
clober_serial.hpp
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
MotorState::position_meter_prev
float position_meter_prev
Definition: clober_serial.hpp:50
CloberSerial::publishOdom
void publishOdom()
Definition: clober_serial.cpp:373
CloberSerial::limitMaxSpeed
float limitMaxSpeed(float speed)
Definition: clober_serial.cpp:239
VehicleConfig::WIDTH
float WIDTH
Definition: clober_serial.hpp:56
ControllerState::current_12v
float current_12v
Definition: clober_serial.hpp:41
VehicleConfig::left_motor
MotorState left_motor
Definition: clober_serial.hpp:61
VehicleConfig::MAX_SPEED
float MAX_SPEED
Definition: clober_serial.hpp:58
MotorCommand::linearVel
float linearVel
Definition: clober_serial.hpp:67
CloberSerial::read_serial
void read_serial(int ms)
Definition: clober_serial.cpp:91
VehicleConfig::MAX_RPM
float MAX_RPM
Definition: clober_serial.hpp:59
CloberSerial::heading_
float heading_
Definition: clober_serial.hpp:141
ros::Time
CloberSerial::readThread_
shared_ptr< thread > readThread_
Definition: clober_serial.hpp:145
CloberSerial::baudrate_
int32_t baudrate_
Definition: clober_serial.hpp:110
CloberSerial::linearVel_
float linearVel_
Definition: clober_serial.hpp:136
CloberSerial::toWheelSpeed
pair< float, float > toWheelSpeed(float v, float w)
Definition: clober_serial.cpp:230
CloberSerial::cmd_vel_timeout_switch_
bool cmd_vel_timeout_switch_
Definition: clober_serial.hpp:115
ControllerState::current_24v
float current_24v
Definition: clober_serial.hpp:42
CloberSerial::posX_
double posX_
Definition: clober_serial.hpp:139
MotorCommand::angularVel
float angularVel
Definition: clober_serial.hpp:68
MotorCommand
Definition: clober_serial.hpp:66
VehicleConfig::right_motor
MotorState right_motor
Definition: clober_serial.hpp:62
MotorState::position_meter_curr
float position_meter_curr
Definition: clober_serial.hpp:51
CloberUtils::toRPM
float toRPM(float w)
Definition: clober_utils.cpp:4
CloberUtils::toRad
float toRad(float enc, int ppr)
Definition: clober_utils.cpp:15
ControllerState::charging_voltage
float charging_voltage
Definition: clober_serial.hpp:40
serial::Timeout
Definition: serial.h:98
ros::NodeHandle
MotorState::current
float current
Definition: clober_serial.hpp:52
ros::Time::now
static Time now()
CloberSerial::angularVel_
float angularVel_
Definition: clober_serial.hpp:137


clober_serial
Author(s):
autogenerated on Wed Mar 2 2022 00:01:24