motor_hardware.cc
Go to the documentation of this file.
1 
32 #include <boost/assign.hpp>
33 
34 #include <boost/math/special_functions/round.hpp>
35 
36 //#define SENSOR_DISTANCE 0.002478
37 
38 // 60 tics per revolution of the motor (pre gearbox)
39 // 17.2328767123
40 // gear ratio of 4.29411764706:1
41 #define TICS_PER_RADIAN (41.0058030317 / 2)
42 #define QTICS_PER_RADIAN (TICS_PER_RADIAN * 4)
43 #define VELOCITY_READ_PER_SECOND \
44  10.0 // read = ticks / (100 ms), so we have scale of 10 for ticks/second
45 #define CURRENT_FIRMWARE_VERSION 24
46 
49  ros::V_string joint_names =
50  boost::assign::list_of("left_wheel_joint")("right_wheel_joint");
51 
52  for (size_t i = 0; i < joint_names.size(); i++) {
53  hardware_interface::JointStateHandle joint_state_handle(
54  joint_names[i], &joints_[i].position, &joints_[i].velocity,
55  &joints_[i].effort);
56  joint_state_interface_.registerHandle(joint_state_handle);
57 
59  joint_state_handle, &joints_[i].velocity_command);
61  }
64 
66  new MotorSerial(serial_params.serial_port, serial_params.baud_rate,
67  serial_params.serial_loop_rate);
68 
69  leftError = nh.advertise<std_msgs::Int32>("left_error", 1);
70  rightError = nh.advertise<std_msgs::Int32>("right_error", 1);
71 
72  pubU50 = nh.advertise<std_msgs::UInt32>("u50", 1);
73  pubS50 = nh.advertise<std_msgs::Int32>("s50", 1);
74  pubU51 = nh.advertise<std_msgs::UInt32>("u51", 1);
75  pubS51 = nh.advertise<std_msgs::Int32>("s51", 1);
76  pubU52 = nh.advertise<std_msgs::UInt32>("u52", 1);
77  pubS52 = nh.advertise<std_msgs::Int32>("s52", 1);
78  pubU53 = nh.advertise<std_msgs::UInt32>("u53", 1);
79  pubS53 = nh.advertise<std_msgs::Int32>("s53", 1);
80  pubU54 = nh.advertise<std_msgs::UInt32>("u54", 1);
81  pubS54 = nh.advertise<std_msgs::Int32>("s54", 1);
82  pubU55 = nh.advertise<std_msgs::UInt32>("u55", 1);
83  pubS55 = nh.advertise<std_msgs::Int32>("s55", 1);
84  pubU56 = nh.advertise<std_msgs::UInt32>("u56", 1);
85  pubS56 = nh.advertise<std_msgs::Int32>("s56", 1);
86  pubU57 = nh.advertise<std_msgs::UInt32>("u57", 1);
87  pubS57 = nh.advertise<std_msgs::Int32>("s57", 1);
88  pubU58 = nh.advertise<std_msgs::UInt32>("u58", 1);
89  pubS58 = nh.advertise<std_msgs::Int32>("s58", 1);
90  pubU59 = nh.advertise<std_msgs::UInt32>("u59", 1);
91  pubS59 = nh.advertise<std_msgs::Int32>("s59", 1);
92 
93  sendPid_count = 0;
94 
96 
103 
104  firmware_version = 0;
105 }
106 
108 
110  while (motor_serial_->commandAvailable()) {
111  MotorMessage mm;
113  if (mm.getType() == MotorMessage::TYPE_RESPONSE) {
114  switch (mm.getRegister()) {
116  if (mm.getData() < CURRENT_FIRMWARE_VERSION) {
117  ROS_FATAL("Firmware version %d, expect %d or above",
119  throw std::runtime_error("Firmware version too low");
120  } else {
121  ROS_INFO("Firmware version %d", mm.getData());
122  firmware_version = mm.getData();
123  }
124  break;
125 
127  int32_t odom = mm.getData();
128  // ROS_ERROR("odom signed %d", odom);
129  int16_t odomLeft = (odom >> 16) & 0xffff;
130  int16_t odomRight = odom & 0xffff;
131  // ROS_ERROR("left %d right %d", odomLeft, odomRight);
132 
133  joints_[0].position += (odomLeft / TICS_PER_RADIAN);
134  joints_[1].position += (odomRight / TICS_PER_RADIAN);
135  break;
136  }
138  std_msgs::Int32 left;
139  std_msgs::Int32 right;
140  int32_t speed = mm.getData();
141  int16_t leftSpeed = (speed >> 16) & 0xffff;
142  int16_t rightSpeed = speed & 0xffff;
143 
144  left.data = leftSpeed;
145  right.data = rightSpeed;
146  leftError.publish(left);
147  rightError.publish(right);
148  break;
149  }
151  int32_t data = mm.getData();
152 
153  if (data & MotorMessage::LIM_M1_PWM) {
154  ROS_ERROR("left PWM limit reached");
155  }
156  if (data & MotorMessage::LIM_M2_PWM) {
157  ROS_ERROR("right PWM limit reached");
158  }
159  if (data & MotorMessage::LIM_M1_INTEGRAL) {
160  ROS_WARN("left Integral limit reached");
161  }
162  if (data & MotorMessage::LIM_M2_INTEGRAL) {
163  ROS_WARN("right Integral limit reached");
164  }
165  break;
166  }
167  default:
168  uint8_t reg = mm.getRegister();
169  int32_t data = mm.getData();
170  std_msgs::UInt32 umsg;
171  std_msgs::Int32 smsg;
172  umsg.data = data;
173  smsg.data = data;
174  switch (reg) {
175  case 0x50:
176  pubU50.publish(umsg);
177  pubS50.publish(smsg);
178  break;
179  case 0x51:
180  pubU51.publish(umsg);
181  pubS51.publish(smsg);
182  break;
183  case 0x52:
184  pubU52.publish(umsg);
185  pubS52.publish(smsg);
186  break;
187  case 0x53:
188  pubU53.publish(umsg);
189  pubS53.publish(smsg);
190  break;
191  case 0x54:
192  pubU54.publish(umsg);
193  pubS54.publish(smsg);
194  break;
195  case 0x55:
196  pubU55.publish(umsg);
197  pubS55.publish(smsg);
198  break;
199  case 0x56:
200  pubU56.publish(umsg);
201  pubS56.publish(smsg);
202  break;
203  case 0x57:
204  pubU57.publish(umsg);
205  pubS57.publish(smsg);
206  break;
207  case 0x58:
208  pubU58.publish(umsg);
209  pubS58.publish(smsg);
210  break;
211  }
212  }
213  }
214  }
215 }
216 
218  MotorMessage both;
221  int16_t left_tics = calculateTicsFromRadians(joints_[0].velocity_command);
222  int16_t right_tics = calculateTicsFromRadians(joints_[1].velocity_command);
223 
224  // The masking with 0x0000ffff is necessary for handling -ve numbers
225  int32_t data = (left_tics << 16) | (right_tics & 0x0000ffff);
226  both.setData(data);
227 
228  std_msgs::Int32 smsg;
229  smsg.data = left_tics;
230  pubS59.publish(smsg);
231 
233 
234  // ROS_ERROR("velocity_command %f rad/s %f rad/s",
235  // joints_[0].velocity_command, joints_[1].velocity_command);
236  // ROS_ERROR("SPEEDS %d %d", left.getData(), right.getData());
237 }
238 
240  MotorMessage version;
243  version.setData(0);
244  motor_serial_->transmitCommand(version);
245 }
246 
248  ROS_ERROR("setting deadman to %d", (int)deadman_timer);
249  MotorMessage mm;
252  mm.setData(deadman_timer);
254 }
255 
262 }
263 
265  std::vector<MotorMessage> commands;
266 
267  // ROS_ERROR("sending PID %d %d %d %d",
268  //(int)p_value, (int)i_value, (int)d_value, (int)denominator_value);
269 
270  // Only send one register at a time to avoid overwhelming serial comms
271  int cycle = (sendPid_count++) % 5;
272 
273  if (cycle == 0 &&
275  ROS_WARN("Setting P to %d", pid_params.pid_proportional);
277  MotorMessage p;
281  commands.push_back(p);
282  }
283 
284  if (cycle == 1 && pid_params.pid_integral != prev_pid_params.pid_integral) {
285  ROS_WARN("Setting I to %d", pid_params.pid_integral);
287  MotorMessage i;
291  commands.push_back(i);
292  }
293 
294  if (cycle == 2 &&
296  ROS_WARN("Setting D to %d", pid_params.pid_derivative);
298  MotorMessage d;
302  commands.push_back(d);
303  }
304 
305  if (cycle == 3 &&
307  ROS_WARN("Setting Denominator to %d", pid_params.pid_denominator);
309  MotorMessage denominator;
311  denominator.setType(MotorMessage::TYPE_WRITE);
312  denominator.setData(pid_params.pid_denominator);
313  commands.push_back(denominator);
314  }
315 
316  if (cycle == 4 &&
319  ROS_WARN("Setting D window to %d", pid_params.pid_moving_buffer_size);
322  MotorMessage winsize;
326  commands.push_back(winsize);
327  }
328 
329  if (commands.size() != 0) {
330  motor_serial_->transmitCommands(commands);
331  }
332 }
333 
334 void MotorHardware::setDebugLeds(bool led_1, bool led_2) {
335  std::vector<MotorMessage> commands;
336 
337  MotorMessage led1;
340  if (led_1) {
341  led1.setData(0x00000001);
342  } else {
343  led1.setData(0x00000000);
344  }
345  commands.push_back(led1);
346 
347  MotorMessage led2;
350  if (led_2) {
351  led2.setData(0x00000001);
352  } else {
353  led2.setData(0x00000000);
354  }
355  commands.push_back(led2);
356 
357  motor_serial_->transmitCommands(commands);
358 }
359 
360 int16_t MotorHardware::calculateTicsFromRadians(double radians) const {
361  return boost::math::iround(radians * QTICS_PER_RADIAN /
363 }
364 
365 double MotorHardware::calculateRadiansFromTics(int16_t tics) const {
366  return (tics * VELOCITY_READ_PER_SECOND / QTICS_PER_RADIAN);
367 }
d
int32_t pid_proportional
int32_t deadman_timer
#define ROS_FATAL(...)
ros::Publisher pubU59
FirmwareParams prev_pid_params
ros::Publisher pubS53
void publish(const boost::shared_ptr< M > &message) const
virtual ~MotorHardware()
int32_t pid_denominator
MotorMessage::MessageTypes getType() const
int16_t calculateTicsFromRadians(double radians) const
ros::Publisher pubU56
void setData(int32_t data)
#define QTICS_PER_RADIAN
int32_t baud_rate
ros::Publisher pubU50
int transmitCommand(MotorMessage command)
Definition: motor_serial.cc:48
hardware_interface::JointStateInterface joint_state_interface_
MotorMessage::Registers getRegister() const
int32_t pid_moving_buffer_size
ros::Publisher pubU53
int transmitCommands(const std::vector< MotorMessage > &commands)
Definition: motor_serial.cc:53
ros::Publisher pubU58
#define ROS_WARN(...)
ros::Publisher rightError
ros::Publisher pubS55
int commandAvailable()
Definition: motor_serial.cc:67
ros::Publisher pubS52
static FirmwareParams firmware_params
Definition: motor_node.cc:44
struct MotorHardware::Joint joints_[2]
std::vector< std::string > V_string
int32_t pid_integral
#define ROS_INFO(...)
void setDeadmanTimer(int32_t deadman)
#define VELOCITY_READ_PER_SECOND
int32_t pid_derivative
void setDebugLeds(bool led1, bool led2)
void setParams(FirmwareParams firmware_params)
FirmwareParams pid_params
ros::Publisher pubU52
ros::Publisher leftError
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::Publisher pubS57
#define TICS_PER_RADIAN
int32_t sendPid_count
void registerHandle(const JointStateHandle &handle)
ros::Publisher pubU57
ros::Publisher pubU55
ros::Publisher pubS58
static CommsParams serial_params
Definition: motor_node.cc:45
void setRegister(MotorMessage::Registers reg)
double serial_loop_rate
double calculateRadiansFromTics(int16_t tics) const
ros::Publisher pubS54
hardware_interface::VelocityJointInterface velocity_joint_interface_
void setType(MotorMessage::MessageTypes type)
ros::Publisher pubU54
ros::Publisher pubS51
#define CURRENT_FIRMWARE_VERSION
MotorMessage receiveCommand()
Definition: motor_serial.cc:58
ros::Publisher pubS50
int32_t deadman_timer
std::string serial_port
MotorSerial * motor_serial_
ros::Publisher pubS59
#define ROS_ERROR(...)
ros::Publisher pubS56
int32_t getData() const
ros::Publisher pubU51
MotorHardware(ros::NodeHandle nh, CommsParams serial_params, FirmwareParams firmware_params)


ubiquity_motor
Author(s):
autogenerated on Mon Jun 10 2019 15:37:24