husky_hardware.cpp
Go to the documentation of this file.
1 
33 #include <boost/assign/list_of.hpp>
34 
35 namespace
36 {
37  const uint8_t LEFT = 0, RIGHT = 1;
38 };
39 
40 namespace husky_base
41 {
42 
46  HuskyHardware::HuskyHardware(ros::NodeHandle nh, ros::NodeHandle private_nh, double target_control_freq)
47  :
48  nh_(nh),
49  private_nh_(private_nh),
50  system_status_task_(husky_status_msg_),
51  power_status_task_(husky_status_msg_),
52  safety_status_task_(husky_status_msg_),
53  software_status_task_(husky_status_msg_, target_control_freq)
54  {
55  private_nh_.param<double>("wheel_diameter", wheel_diameter_, 0.3302);
56  private_nh_.param<double>("max_accel", max_accel_, 5.0);
57  private_nh_.param<double>("max_speed", max_speed_, 1.0);
58  private_nh_.param<double>("polling_timeout_", polling_timeout_, 10.0);
59 
60  std::string port;
61  private_nh_.param<std::string>("port", port, "/dev/prolific");
62 
64  horizon_legacy::configureLimits(max_speed_, max_accel_);
68  }
69 
74  {
77  if (enc)
78  {
79  for (int i = 0; i < 4; i++)
80  {
81  joints_[i].position_offset = linearToAngular(enc->getTravel(i % 2));
82  }
83  }
84  else
85  {
86  ROS_ERROR("Could not get encoder data to calibrate travel offset");
87  }
88  }
89 
94  {
97  std::ostringstream hardware_id_stream;
98  hardware_id_stream << "Husky " << info->getModel() << "-" << info->getSerial();
99 
100  diagnostic_updater_.setHardwareID(hardware_id_stream.str());
105  diagnostic_publisher_ = nh_.advertise<husky_msgs::HuskyStatus>("status", 10);
106  }
107 
108 
113  {
114  ros::V_string joint_names = boost::assign::list_of("front_left_wheel")
115  ("front_right_wheel")("rear_left_wheel")("rear_right_wheel");
116  for (unsigned int i = 0; i < joint_names.size(); i++)
117  {
118  hardware_interface::JointStateHandle joint_state_handle(joint_names[i],
119  &joints_[i].position, &joints_[i].velocity,
120  &joints_[i].effort);
121  joint_state_interface_.registerHandle(joint_state_handle);
122 
123  hardware_interface::JointHandle joint_handle(
124  joint_state_handle, &joints_[i].velocity_command);
126  }
129  }
130 
135  {
137  husky_status_msg_.header.stamp = ros::Time::now();
139  }
140 
145  {
146 
149  if (enc)
150  {
151  ROS_DEBUG_STREAM("Received travel information (L:" << enc->getTravel(LEFT) << " R:" << enc->getTravel(RIGHT) << ")");
152  for (int i = 0; i < 4; i++)
153  {
154  double delta = linearToAngular(enc->getTravel(i % 2)) - joints_[i].position - joints_[i].position_offset;
155 
156  // detect suspiciously large readings, possibly from encoder rollover
157  if (std::abs(delta) < 1.0)
158  {
159  joints_[i].position += delta;
160  }
161  else
162  {
163  // suspicious! drop this measurement and update the offset for subsequent readings
164  joints_[i].position_offset += delta;
165  ROS_DEBUG("Dropping overflow measurement from encoder");
166  }
167  }
168  }
169 
172  if (speed)
173  {
174  ROS_DEBUG_STREAM("Received linear speed information (L:" << speed->getLeftSpeed() << " R:" << speed->getRightSpeed() << ")");
175  for (int i = 0; i < 4; i++)
176  {
177  if (i % 2 == LEFT)
178  {
179  joints_[i].velocity = linearToAngular(speed->getLeftSpeed());
180  }
181  else
182  { // assume RIGHT
183  joints_[i].velocity = linearToAngular(speed->getRightSpeed());
184  }
185  }
186  }
187  }
188 
193  {
194  double diff_speed_left = angularToLinear(joints_[LEFT].velocity_command);
195  double diff_speed_right = angularToLinear(joints_[RIGHT].velocity_command);
196 
197  limitDifferentialSpeed(diff_speed_left, diff_speed_right);
198 
199  horizon_legacy::controlSpeed(diff_speed_left, diff_speed_right, max_accel_, max_accel_);
200  }
201 
206  {
208  }
209 
213  void HuskyHardware::limitDifferentialSpeed(double &diff_speed_left, double &diff_speed_right)
214  {
215  double large_speed = std::max(std::abs(diff_speed_left), std::abs(diff_speed_right));
216 
217  if (large_speed > max_speed_)
218  {
219  diff_speed_left *= max_speed_ / large_speed;
220  diff_speed_right *= max_speed_ / large_speed;
221  }
222  }
223 
227  double HuskyHardware::linearToAngular(const double &travel) const
228  {
229  return travel / wheel_diameter_ * 2;
230  }
231 
235  double HuskyHardware::angularToLinear(const double &angle) const
236  {
237  return angle * wheel_diameter_ / 2;
238  }
239 
240 
241 } // namespace husky_base
void connect(std::string port)
ros::Publisher diagnostic_publisher_
HuskySoftwareDiagnosticTask software_status_task_
void publish(const boost::shared_ptr< M > &message) const
HuskyHardwareDiagnosticTask< clearpath::DataSafetySystemStatus > safety_status_task_
husky_msgs::HuskyStatus husky_status_msg_
void setHardwareID(const std::string &hwid)
void add(const std::string &name, TaskFunction f)
void reportLoopDuration(const ros::Duration &duration)
struct husky_base::HuskyHardware::Joint joints_[4]
hardware_interface::JointStateInterface joint_state_interface_
std::vector< std::string > V_string
diagnostic_updater::Updater diagnostic_updater_
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ros::NodeHandle private_nh_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
HuskyHardwareDiagnosticTask< clearpath::DataSystemStatus > system_status_task_
#define ROS_DEBUG_STREAM(args)
void registerHandle(const JointStateHandle &handle)
double linearToAngular(const double &travel) const
hardware_interface::VelocityJointInterface velocity_joint_interface_
double angularToLinear(const double &angle) const
static Time now()
void configureLimits(double max_speed, double max_accel)
static Ptr requestData(double timeout)
HuskyHardware(ros::NodeHandle nh, ros::NodeHandle private_nh, double target_control_freq)
#define ROS_ERROR(...)
void limitDifferentialSpeed(double &travel_speed_left, double &travel_speed_right)
HuskyHardwareDiagnosticTask< clearpath::DataPowerSystem > power_status_task_
#define ROS_DEBUG(...)
void controlSpeed(double speed_left, double speed_right, double accel_left, double accel_right)


husky_base
Author(s): Mike Purvis , Paul Bovbel
autogenerated on Fri Oct 2 2020 03:40:07