tmcl_bldc_motor.cpp
Go to the documentation of this file.
1 
6 #include "tmcl_bldc_motor.h"
7 
9 
10 /* Constructor */
12  uint16_t module_number, uint8_t motor_number) :
13  Motor(p_nh, p_tmcl_interpreter, module_number, motor_number)
14 {
16 
17  ROS_DEBUG_STREAM("[BLDCMotor::" << __func__ << "] called");
18 
19  /* Save StatusFlags RegisterNames and StatusFlags RegisterShift to vector */
20  const std::string s_statusflags_reg_name = s_node_name_ + "/StatusFlags_Reg_name";
21  if(!p_nh_->getParam(s_statusflags_reg_name, param_statusflags_reg_name_))
22  {
24  ROS_WARN_STREAM("[" << __func__ << "] StatusFlags Register Names are not available.");
25  }
26  const std::string s_statusflags_reg_shift = s_node_name_ + "/StatusFlags_Reg_shift";
28  {
30  ROS_WARN_STREAM("[" << __func__ << "] StatusFlags Register Shift are not available.");
31  }
32 
33  /* Check if Reg name and Reg shift vectors have the same length/size */
35  {
37  ROS_WARN_STREAM("[" << __func__ << "] Missing index for StatusFlagsRegisterName / StatusFlagsRegisterShift."
38  "Check autogenerated YAML. StatusFlags wont be used!");
39  }
40 }
41 
42 /* Destructor */
44 {
45  ROS_DEBUG_STREAM("[BLDCMotor::" << __func__ << "] called");
46 }
47 
49 {
50  int32_t val = 0;
51 
52  ROS_INFO_STREAM("[BLDCMotor::" << __func__ << "] called");
53 
54  if(p_tmcl_interpreter_->executeCmd(TMCL_CMD_GAP, "CommutationMode", motor_number_, &val))
55  {
57  }
58  else
59  {
61  ROS_WARN_STREAM("[" << __func__ << "] \"CommutationMode\" is not available. Setting CommutationMode to Disable");
62  }
63 
64  if(p_tmcl_interpreter_->executeCmd(TMCL_CMD_GAP, "PositionScalerM", motor_number_, &val))
65  {
66  position_scaler_ = val;
67  }
68  else
69  {
70  position_scaler_ = 0;
71  ROS_WARN_STREAM("[" << __func__ << "] \"PositionScalerM\" is not available");
72 
75  {
76  encoder_steps_ = val;
77  }
78  else
79  {
80  encoder_steps_ = 0;
81  ROS_WARN_STREAM("[" << __func__ << "] \"EncoderSteps\" is not available.");
82  }
83  }
84 
85  /* Print units of each commands */
86  if(param_wheel_diameter_ == 0)
87  {
88  ROS_INFO_STREAM("[" << __func__ << "] Velocity unit: rpm");
89  }
90  else
91  {
92  ROS_INFO_STREAM("[" << __func__ << "] Velocity unit: m/s");
93  }
94  if(position_scaler_ == 0 && encoder_steps_ == 0)
95  {
96  ROS_INFO_STREAM("[" << __func__ << "] Position unit: pulses");
97  }
98  else
99  {
100  ROS_INFO_STREAM("[" << __func__ << "] Position unit: angular degrees");
101  }
102 
103  ROS_INFO_STREAM("[" << __func__ << "] Torque unit: mA");
104 
105  initPublisher();
106  this->initSubscriber();
107  ROS_INFO("[%s] Motor %d Initialized!\n", __func__, motor_number_);
108 }
109 
110 /* Publisher Callback */
112 {
113  int32_t val = 0;
114  int32_t status_flag = 0;
115  uint8_t bin_index = 0;
116  uint8_t array_index = 0;
117  std::string binary = " ";
118  std::string status = " ";
119 
120  tmc_info_msg_.header.stamp = ros::Time::now();
121  tmc_info_msg_.header.seq = seq_ctr_;
122  tmc_info_msg_.header.frame_id = frame_id_;
123  tmc_info_msg_.interface_name = param_comm_interface_name_;
124  tmc_info_msg_.motor_number = motor_number_;
125 
126  /* Initialize messages to 0 first */
127  tmc_info_msg_.board_voltage = 0;
128  tmc_info_msg_.status_flag = 0;
129  tmc_info_msg_.velocity = 0;
130  tmc_info_msg_.position = 0;
131  tmc_info_msg_.torque = 0;
132 
133  if(p_tmcl_interpreter_->executeCmd(TMCL_CMD_GAP, "SupplyVoltage", motor_number_, &val))
134  {
135  tmc_info_msg_.board_voltage = val / 10; //converts mV to V
136  }
137  else
138  {
139  ROS_DEBUG_STREAM("[" << __func__ << "] Failed to get SupplyVoltage");
140  }
141 
142  if(p_tmcl_interpreter_->executeCmd(TMCL_CMD_GAP, "StatusFlags", motor_number_, &val))
143  {
144  tmc_info_msg_.status_flag = val;
145  status_flag = tmc_info_msg_.status_flag;
146  }
147  else
148  {
149  ROS_DEBUG_STREAM("[" << __func__ << "] Failed to get StatusFlags");
150  }
151 
152  //Parsing StatusFlags value to display status in string
154  {
155  while(status_flag)
156  {
157  if(status_flag & 1)
158  {
159  binary+='1';
160  }
161  else
162  {
163  binary+='0';
164  }
165  status_flag>>=1;
166  }
167 
168  for(bin_index = 0; bin_index < binary.length(); bin_index++)
169  {
170  if(binary[bin_index] == '1')
171  {
172  while(array_index < param_statusflags_reg_shift_.size())
173  {
174  if(bin_index == param_statusflags_reg_shift_[array_index])
175  {
176  status += param_statusflags_reg_name_[array_index - 1] + ", ";
177  array_index = 0;
178  break;
179  }
180  array_index++;
181  }
182  }
183  }
184  tmc_info_msg_.status = status;
185  }
186  else
187  {
188  tmc_info_msg_.status = "StatusFlags Registers Not Available";
189  }
190 
191  /* Velocity, Position, Torque */
193  {
194  if(p_tmcl_interpreter_->executeCmd(TMCL_CMD_GAP, "ActualVelocity", motor_number_, &val))
195  {
196  //converts rpm to linear velocity
197  if(param_wheel_diameter_ == 0)
198  {
199  tmc_info_msg_.velocity = val * param_add_ratio_vel_;
200  }
201  else
202  {
204  }
205  }
206  else
207  {
208  ROS_DEBUG_STREAM("[" << __func__ << "] Failed to get ActualVelocity");
209  }
210  }
211 
213  {
214  if(p_tmcl_interpreter_->executeCmd(TMCL_CMD_GAP, "ActualPosition", motor_number_, &val))
215  {
216  //converts steps to degrees
217  if(position_scaler_ > 0)
218  {
220  }
221  else if(encoder_steps_ > 0)
222  {
224  }
225  else
226  {
227  tmc_info_msg_.position = val * param_add_ratio_pos_;
228  }
229  }
230  else
231  {
232  ROS_DEBUG_STREAM("[" << __func__ << "] Failed to get ActualPosition");
233  }
234  }
235 
237  {
238  if(p_tmcl_interpreter_->executeCmd(TMCL_CMD_GAP, "ActualTorque", motor_number_, &val))
239  {
240  tmc_info_msg_.torque = val * param_add_ratio_trq_;
241  }
242  else
243  {
244  ROS_DEBUG_STREAM("[" << __func__ << "] Failed to get ActualTorque");
245  }
246  }
247 
249  seq_ctr_++;
250 }
251 
252 /* Initialize Subscriber */
254 {
255  ROS_INFO_STREAM("[BLDCMotor::" << __func__ << "] called");
256 
258  {
259  ROS_INFO_STREAM("[" << __func__ << "] CommutationMode : OPENLOOP");
263  }
265  {
266  ROS_INFO_STREAM("[" << __func__ << "] CommutationMode : CLOSEDLOOP");
268  }
269  /* Note: No subscriber if Commutation Mode is Disabled */
270 }
271 
272 /* Subscriber Callback */
273 void BLDCMotor::cmdVelCallback(const geometry_msgs::Twist& msg)
274 {
275  float val = msg.linear.x;
276  int32_t board_val = 0;
277 
278  //If wheel diameter is set to 0 (or no wheels connected), the input value for linearX is equal to motors rpm
279  if(param_wheel_diameter_ == 0)
280  {
281  board_val = val / param_add_ratio_vel_;
282  }
283  else
284  {
285  //Formula to convert linear value to rpm (unit that the board accepts)
286  board_val = val * (SECS_TO_MIN / (PI * param_wheel_diameter_)) * (1 / param_add_ratio_vel_);
287  }
288 
289  ROS_DEBUG_STREAM("[" << __func__ << "] Subscriber callback entered, received: " << val
290  << " board value: " << board_val);
291 
292  if(board_val >= 0)
293  {
295  {
296  ROS_DEBUG_STREAM("\n[" << __func__ << "] Subscriber callback exited successfully");
297  }
298  else
299  {
300  ROS_ERROR_STREAM("[" << __func__ << "] Failed to set Velocity");
301  }
302  }
303  else
304  {
305  board_val = abs(board_val);
307  {
308  ROS_DEBUG_STREAM("\n[" << __func__ << "] Subscriber callback exited successfully");
309  }
310  else
311  {
312  ROS_ERROR_STREAM("[" << __func__ << "] Failed to set Velocity");
313  }
314  }
315 }
316 void BLDCMotor::cmdAbsPosCallback(const std_msgs::Int32 msg)
317 {
318  float convert_const_deg = 0.00;
319  int32_t unit_val = 0;
320  int32_t val = msg.data;
321 
322  //convert input(degrees) to unit
323  if(position_scaler_ > 0)
324  {
325  convert_const_deg = ((float)position_scaler_ / ANGULAR_FULL_ROTATION) * (1 / param_add_ratio_pos_);
326  }
327  else if(encoder_steps_ > 0)
328  {
329  convert_const_deg = ((float)encoder_steps_ / ANGULAR_FULL_ROTATION) * (1 / param_add_ratio_pos_);
330  }
331  else
332  {
333  //inverting position additional ratio
334  convert_const_deg = 1 / param_add_ratio_pos_;
335  }
336 
337  unit_val = val * convert_const_deg;
338 
339  ROS_DEBUG_STREAM("[" << __func__ << "] Subscriber callback entered, received: " << val << " board value: "
340  << unit_val);
341 
343  {
344  ROS_DEBUG_STREAM("\n[" << __func__ << "] Subscriber callback exited successfully");
345  }
346  else
347  {
348  ROS_ERROR_STREAM("[" << __func__ << "] Failed to set Absolute Position");
349  }
350 }
351 void BLDCMotor::cmdRelPosCallback(const std_msgs::Int32 msg)
352 {
353  float convert_const_deg = 0;
354  int32_t unit_val = 0;
355  int32_t val = msg.data;
356 
357  //convert input(degrees) to unit
358  if(position_scaler_ > 0)
359  {
360  convert_const_deg = ((float)position_scaler_ / ANGULAR_FULL_ROTATION) * (1 / param_add_ratio_pos_);
361  }
362  else if(encoder_steps_ > 0)
363  {
364  convert_const_deg = ((float)encoder_steps_ / ANGULAR_FULL_ROTATION) * (1 / param_add_ratio_pos_);
365  }
366  else
367  {
368  //inverting position additional ratio
369  convert_const_deg = 1 / param_add_ratio_pos_;
370  }
371 
372  unit_val = val * convert_const_deg;
373 
374  ROS_DEBUG_STREAM("[" << __func__ << "] Subscriber callback entered, received: " << val << " board value: "
375  << unit_val);
376 
378  {
379  ROS_DEBUG_STREAM("\n[" << __func__ << "] Subscriber callback exited successfully");
380  }
381  else
382  {
383  ROS_ERROR_STREAM("[" << __func__ << "] Failed to set Relative Position");
384  }
385 }
BLDCMotor::position_scaler_
int32_t position_scaler_
Definition: tmcl_bldc_motor.h:43
Motor::param_wheel_diameter_
float param_wheel_diameter_
Definition: tmcl_motor.h:82
ROS_ERROR_STREAM
#define ROS_ERROR_STREAM(args)
Motor::tmc_cmd_relpos_sub_
ros::Subscriber tmc_cmd_relpos_sub_
Definition: tmcl_motor.h:59
BLDCMotor::BLDCMotor
BLDCMotor(ros::NodeHandle *p_nh, TmclInterpreter *p_tmcl_interpreter, uint16_t module_number, uint8_t motor_number)
Definition: tmcl_bldc_motor.cpp:11
bldc_comm_mode_t
bldc_comm_mode_t
Definition: tmcl_bldc_motor.h:12
TMCL_CMD_GAP
@ TMCL_CMD_GAP
Definition: tmcl_interpreter.h:64
Motor::s_node_name_
std::string s_node_name_
Definition: tmcl_motor.h:68
ros::NodeHandle::getParam
bool getParam(const std::string &key, bool &b) const
Motor::param_add_ratio_vel_
float param_add_ratio_vel_
Definition: tmcl_motor.h:83
Motor::frame_id_
std::string frame_id_
Definition: tmcl_motor.h:70
TmclInterpreter::executeCmd
bool executeCmd(tmcl_cmd_t cmd, uint8_t type, uint8_t motor, int32_t *val)
Definition: tmcl_interpreter.cpp:75
PI
const double PI
Definition: tmcl_motor.h:20
BLDCMotor::init
void init() override
Definition: tmcl_bldc_motor.cpp:48
BLDCMotor::param_statusflags_reg_name_
std::vector< std::string > param_statusflags_reg_name_
Definition: tmcl_bldc_motor.h:46
BLDCMotor::cmdAbsPosCallback
void cmdAbsPosCallback(const std_msgs::Int32 msg) override
Definition: tmcl_bldc_motor.cpp:316
ANGULAR_FULL_ROTATION
const uint16_t ANGULAR_FULL_ROTATION
Definition: tmcl_motor.h:24
Motor::param_tmc_cmd_vel_topic_
std::string param_tmc_cmd_vel_topic_
Definition: tmcl_motor.h:75
tmcl_bldc_motor.h
ROS_DEBUG_STREAM
#define ROS_DEBUG_STREAM(args)
BLDC_DISABLED_MOTOR
@ BLDC_DISABLED_MOTOR
Definition: tmcl_bldc_motor.h:14
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
Motor::tmc_cmd_abspos_sub_
ros::Subscriber tmc_cmd_abspos_sub_
Definition: tmcl_motor.h:58
BLDCMotor::comm_mode_
bldc_comm_mode_t comm_mode_
Definition: tmcl_bldc_motor.h:49
Motor::initPublisher
void initPublisher()
Definition: tmcl_motor.cpp:167
Motor::tmc_cmd_vel_sub_
ros::Subscriber tmc_cmd_vel_sub_
Definition: tmcl_motor.h:57
TMCL_CMD_ROL
@ TMCL_CMD_ROL
Definition: tmcl_interpreter.h:60
ROS_WARN_STREAM
#define ROS_WARN_STREAM(args)
BLDCMotor::~BLDCMotor
~BLDCMotor() override
Definition: tmcl_bldc_motor.cpp:43
BLDCMotor::encoder_steps_
int32_t encoder_steps_
Definition: tmcl_bldc_motor.h:44
Motor::param_tmc_cmd_abspos_topic_
std::string param_tmc_cmd_abspos_topic_
Definition: tmcl_motor.h:76
Motor::tmc_info_pub_
ros::Publisher tmc_info_pub_
Definition: tmcl_motor.h:44
BLDCMotor::rosPublishTmcInfo
void rosPublishTmcInfo(const ros::TimerEvent &event) override
Definition: tmcl_bldc_motor.cpp:111
TmclInterpreter
Definition: tmcl_interpreter.h:98
BLDC_OPENLOOP_MOTOR
@ BLDC_OPENLOOP_MOTOR
Definition: tmcl_bldc_motor.h:15
Motor::p_tmcl_interpreter_
TmclInterpreter * p_tmcl_interpreter_
Definition: tmcl_motor.h:64
BLDCMotor::cmdRelPosCallback
void cmdRelPosCallback(const std_msgs::Int32 msg) override
Definition: tmcl_bldc_motor.cpp:351
Motor::p_nh_
ros::NodeHandle * p_nh_
Definition: tmcl_motor.h:63
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())
ros::TimerEvent
ROS_INFO_STREAM
#define ROS_INFO_STREAM(args)
Motor::param_pub_actual_pos_
bool param_pub_actual_pos_
Definition: tmcl_motor.h:80
Motor::param_pub_actual_trq_
bool param_pub_actual_trq_
Definition: tmcl_motor.h:81
Motor::seq_ctr_
uint32_t seq_ctr_
Definition: tmcl_motor.h:49
BLDCMotor::cmdVelCallback
void cmdVelCallback(const geometry_msgs::Twist &msg) override
Definition: tmcl_bldc_motor.cpp:273
Motor::tmc_info_msg_
adi_tmcl::TmcInfo tmc_info_msg_
Definition: tmcl_motor.h:45
Motor::param_add_ratio_pos_
float param_add_ratio_pos_
Definition: tmcl_motor.h:84
Motor::motor_number_
uint8_t motor_number_
Definition: tmcl_motor.h:72
SECS_TO_MIN
const uint8_t SECS_TO_MIN
Definition: tmcl_motor.h:21
Motor::param_tmc_cmd_relpos_topic_
std::string param_tmc_cmd_relpos_topic_
Definition: tmcl_motor.h:77
Motor::initSubscriber
virtual void initSubscriber()
Definition: tmcl_motor.cpp:281
Motor::param_add_ratio_trq_
float param_add_ratio_trq_
Definition: tmcl_motor.h:85
Motor
Definition: tmcl_motor.h:26
TMCL_CMD_MVP
@ TMCL_CMD_MVP
Definition: tmcl_interpreter.h:62
BLDC_CLOSEDLOOP_MOTOR
@ BLDC_CLOSEDLOOP_MOTOR
Definition: tmcl_bldc_motor.h:16
TMCL_CMD_ROR
@ TMCL_CMD_ROR
Definition: tmcl_interpreter.h:59
Motor::param_pub_actual_vel_
bool param_pub_actual_vel_
Definition: tmcl_motor.h:79
BLDCMotor::param_statusflags_reg_shift_
std::vector< int > param_statusflags_reg_shift_
Definition: tmcl_bldc_motor.h:47
ROS_INFO
#define ROS_INFO(...)
BLDCMotor::b_statusflags_register_available_
bool b_statusflags_register_available_
Definition: tmcl_bldc_motor.h:45
BLDCMotor::initSubscriber
void initSubscriber() override
Definition: tmcl_bldc_motor.cpp:253
Motor::param_comm_interface_name_
std::string param_comm_interface_name_
Definition: tmcl_motor.h:67
ros::NodeHandle
ros::Time::now
static Time now()


adi_tmcl
Author(s):
autogenerated on Wed Apr 2 2025 02:43:01