abstract_stepper_driver.cpp
Go to the documentation of this file.
1 /*
2  abstract_motor_driver.cpp
3  Copyright (C) 2020 Niryo
4  All rights reserved.
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13  You should have received a copy of the GNU General Public License
14  along with this program. If not, see <http:// www.gnu.org/licenses/>.
15 */
16 
18 #include "common/model/stepper_command_type_enum.hpp"
19 
20 #include <cassert>
21 #include <memory>
22 #include <ros/ros.h>
23 #include <string>
24 #include <utility>
25 #include <vector>
26 #include <algorithm>
27 
28 using ::common::model::EStepperCalibrationStatus;
29 using ::common::model::EStepperCommandType;
30 
31 namespace ttl_driver
32 {
33 
34 inline constexpr auto MAX_CONVEYOR_RPM = 50;
35 
39 AbstractStepperDriver::AbstractStepperDriver(std::shared_ptr<dynamixel::PortHandler> portHandler,
40  std::shared_ptr<dynamixel::PacketHandler> packetHandler)
41  : AbstractMotorDriver(std::move(portHandler), std::move(packetHandler))
42 {
43 }
44 
49 std::string AbstractStepperDriver::str() const
50 {
51  return "Abstract Stepper Driver (" + AbstractMotorDriver::str() + ")";
52 }
53 
58 int AbstractStepperDriver::writeSingleCmd(const std::unique_ptr<common::model::AbstractTtlSingleMotorCmd> &cmd)
59 {
60  if (cmd->isValid() && cmd->isStepperCmd())
61  {
62  switch (EStepperCommandType(cmd->getCmdType()))
63  {
64  case EStepperCommandType::CMD_TYPE_VELOCITY:
65  return writeVelocityGoal(cmd->getId(), cmd->getParam());
66  case EStepperCommandType::CMD_TYPE_POSITION:
67  return writePositionGoal(cmd->getId(), cmd->getParam());
68  case EStepperCommandType::CMD_TYPE_TORQUE:
69  return writeTorquePercentage(cmd->getId(), static_cast<uint8_t>(cmd->getParam()));
70  case EStepperCommandType::CMD_TYPE_LEARNING_MODE:
71  return writeTorquePercentage(cmd->getId(), static_cast<uint8_t>(!cmd->getParam()));
72  case EStepperCommandType::CMD_TYPE_CALIBRATION:
73  return startHoming(cmd->getId());
74  case EStepperCommandType::CMD_TYPE_FACTORY_CALIBRATION:
75  return factoryCalibration(cmd->getId(), cmd->getParam());
76  case EStepperCommandType::CMD_TYPE_CALIBRATION_SETUP:
77  return writeHomingSetup(cmd->getId(), static_cast<uint8_t>(cmd->getParams().at(0)),
78  static_cast<uint8_t>(cmd->getParams().at(1)));
79  case EStepperCommandType::CMD_TYPE_PING:
80  return ping(cmd->getId());
81  case EStepperCommandType::CMD_TYPE_CONVEYOR: {
82  std::vector<uint32_t> params = cmd->getParams();
83  if (!params[0])
84  {
85  return writeVelocityGoal(cmd->getId(), 0);
86  }
87 
88  // convert direction and speed into signed speed
89  uint32_t dir = static_cast<uint32_t>(cmd->getParams().at(2));
90  uint32_t speed_percent = std::clamp(static_cast<uint32_t>(cmd->getParams().at(1)), 0u, 100u);
91  // normal warning : we need to put an int32 inside an uint32_t
92  uint32_t speed =
93  static_cast<uint32_t>(dir * static_cast<int>(speed_percent * MAX_CONVEYOR_RPM / (100 * velocityUnit())));
94  ROS_INFO("AbstractStepperDriver::writeSingleCmd: speed = %d", speed);
95  return writeVelocityGoal(cmd->getId(), speed);
96  }
97  case EStepperCommandType::CMD_TYPE_VELOCITY_PROFILE:
98  return writeVelocityProfile(cmd->getId(), cmd->getParams());
99  case EStepperCommandType::CMD_TYPE_OPERATING_MODE:
100  return writeControlMode(cmd->getId(), static_cast<uint8_t>(cmd->getParam()));
101  default:
102  std::cout << "Command not implemented " << cmd->getCmdType() << std::endl;
103  }
104  }
105 
106  std::cout << "AbstractStepperDriver::writeSingleCmd: Command not validated : " << cmd->str() << std::endl;
107  return -1;
108 }
109 
116 int AbstractStepperDriver::writeSyncCmd(int type, const std::vector<uint8_t> &ids, const std::vector<uint32_t> &params)
117 {
118  assert(!ids.empty() && "AbstractStepperDriver::writeSyncCmdwriteSyncCmd: ids is empty");
119  assert(!params.empty() && "AbstractStepperDriver::writeSyncCmdwriteSyncCmd: params is empty");
120 
121  switch (EStepperCommandType(type))
122  {
123  case EStepperCommandType::CMD_TYPE_POSITION:
124  return syncWritePositionGoal(ids, params);
125  case EStepperCommandType::CMD_TYPE_VELOCITY:
126  return syncWriteVelocityGoal(ids, params);
127  case EStepperCommandType::CMD_TYPE_TORQUE: {
128  std::vector<uint8_t> params_conv;
129  params_conv.reserve(params.size());
130  for (auto const &p : params)
131  {
132  params_conv.emplace_back(static_cast<uint8_t>(p));
133  }
134  return syncWriteTorquePercentage(ids, params_conv);
135  }
136  case EStepperCommandType::CMD_TYPE_LEARNING_MODE: {
137  std::vector<uint8_t> params_inv;
138  params_inv.reserve(params.size());
139  for (auto const &p : params)
140  {
141  params_inv.emplace_back(!p);
142  }
143  return syncWriteTorquePercentage(ids, params_inv);
144  }
145  case EStepperCommandType::CMD_TYPE_WRITE_HOMING_ABS_POSITION:
146  return syncWriteHomingAbsPosition(ids, params);
147  default:
148  std::cout << "Command not implemented " << type << std::endl;
149  }
150 
151  std::cout << "AbstractStepperDriver::writeSyncCmd : Command not validated : " << type << std::endl;
152  return -1;
153 }
154 
160 std::string AbstractStepperDriver::interpretFirmwareVersion(uint32_t fw_version) const
161 {
162  auto v_major = static_cast<uint8_t>(fw_version >> 24);
163  auto v_minor = static_cast<uint8_t>((fw_version >> 16) & 0xFF);
164  auto v_patch = static_cast<uint16_t>(fw_version & 0xFFFF);
165 
166  std::ostringstream ss;
167  ss << std::to_string(v_major) << "." << std::to_string(v_minor) << "." << std::to_string(v_patch);
168  std::string version = ss.str();
169 
170  return version;
171 }
172 
178 std::string AbstractStepperDriver::interpretErrorState(uint32_t hw_state) const
179 {
180  std::string hardware_message;
181 
182  if (hw_state & 1 << 0) // 0b00000001
183  {
184  hardware_message += "Input Voltage";
185  }
186  if (hw_state & 1 << 2) // 0b00000100
187  {
188  if (!hardware_message.empty())
189  hardware_message += ", ";
190  hardware_message += "OverHeating";
191  }
192  if (hw_state & 1 << 3) // 0b00001000
193  {
194  if (!hardware_message.empty())
195  hardware_message += ", ";
196  hardware_message += "Motor Encoder";
197  }
198  if (hw_state & 1 << 7) // 0b10000000 => added by us : disconnected error
199  {
200  if (!hardware_message.empty())
201  hardware_message += ", ";
202  hardware_message += "Disconnection";
203  }
204 
205  if (!hardware_message.empty())
206  hardware_message += " Error";
207 
208  return hardware_message;
209 }
210 
216 common::model::EStepperCalibrationStatus AbstractStepperDriver::interpretHomingData(uint8_t status) const
217 {
218  EStepperCalibrationStatus homing_status{ EStepperCalibrationStatus::UNINITIALIZED };
219 
220  switch (status)
221  {
222  case 0:
223  homing_status = EStepperCalibrationStatus::UNINITIALIZED;
224  break;
225  case 1:
226  homing_status = EStepperCalibrationStatus::IN_PROGRESS;
227  break;
228  case 2:
229  homing_status = EStepperCalibrationStatus::OK;
230  break;
231  case 3:
232  homing_status = EStepperCalibrationStatus::FAIL;
233  break;
234  default:
235  homing_status = EStepperCalibrationStatus::FAIL;
236  break;
237  }
238 
239  return homing_status;
240 }
241 
247 int AbstractStepperDriver::factoryCalibration(const uint8_t id, const uint32_t &command)
248 {
249  ROS_WARN("AbstractStepperDriver::factoryCalibration - not implemented");
250 
251  return 0;
252 }
253 
257 int AbstractStepperDriver::readConveyorVelocity(uint8_t id, int32_t &velocity_percent, int32_t &direction)
258 {
259  uint32_t unsigned_present_velocity = 0;
260  auto res = readVelocity(id, unsigned_present_velocity);
261  if (res != COMM_SUCCESS)
262  {
263  ROS_ERROR("AbstractStepperDriver::readConveyorVelocity: readVelocity failed with error %d", res);
264  return res;
265  }
266 
267  // The typed returned by the hardware is actually an int32_t, it is just that the API returns it as an uint32_t
268  // We can safely cast it to int32_t
269  int32_t present_velocity = static_cast<int32_t>(unsigned_present_velocity);
270 
271  auto velocity_unit = velocityUnit();
272  auto velocity_rpms = present_velocity * velocity_unit;
273  direction = present_velocity > 0 ? 1 : -1;
274  velocity_percent = static_cast<int32_t>(std::abs(velocity_rpms * 100 / MAX_CONVEYOR_RPM));
275  return COMM_SUCCESS;
276 }
277 
278 } // namespace ttl_driver
ttl_driver::AbstractStepperDriver::interpretHomingData
virtual common::model::EStepperCalibrationStatus interpretHomingData(uint8_t status) const
AbstractStepperDriver::interpretHomingData.
Definition: abstract_stepper_driver.cpp:216
ttl_driver::AbstractStepperDriver::interpretErrorState
std::string interpretErrorState(uint32_t hw_state) const override
AbstractStepperDriver::interpretErrorState.
Definition: abstract_stepper_driver.cpp:178
ttl_driver::MAX_CONVEYOR_RPM
constexpr auto MAX_CONVEYOR_RPM
Definition: abstract_stepper_driver.cpp:34
ttl_driver::AbstractStepperDriver::factoryCalibration
virtual int factoryCalibration(const uint8_t id, const uint32_t &command)
AbstractStepperDriver::factoryCalibration.
Definition: abstract_stepper_driver.cpp:247
ttl_driver::AbstractStepperDriver::writeHomingSetup
virtual int writeHomingSetup(uint8_t id, uint8_t direction, uint8_t stall_threshold)=0
ttl_driver::AbstractStepperDriver::str
std::string str() const override
AbstractStepperDriver::str.
Definition: abstract_stepper_driver.cpp:49
ttl_driver::AbstractStepperDriver::syncWriteHomingAbsPosition
virtual int syncWriteHomingAbsPosition(const std::vector< uint8_t > &id_list, const std::vector< uint32_t > &abs_position)=0
ttl_driver::AbstractTtlDriver::ping
virtual int ping(uint8_t id)
AbstractTtlDriver::ping.
Definition: abstract_ttl_driver.cpp:49
ttl_driver::AbstractMotorDriver::syncWritePositionGoal
virtual int syncWritePositionGoal(const std::vector< uint8_t > &id_list, const std::vector< uint32_t > &position_list)=0
ttl_driver::AbstractStepperDriver::writeSingleCmd
int writeSingleCmd(const std::unique_ptr< common::model::AbstractTtlSingleMotorCmd > &cmd) override
AbstractStepperDriver::writeSingleCmd.
Definition: abstract_stepper_driver.cpp:58
ttl_driver::AbstractStepperDriver::AbstractStepperDriver
AbstractStepperDriver()=default
ttl_driver::AbstractStepperDriver::interpretFirmwareVersion
std::string interpretFirmwareVersion(uint32_t fw_version) const override
AbstractStepperDriver::interpretFirmwareVersion.
Definition: abstract_stepper_driver.cpp:160
ttl_driver::AbstractMotorDriver::writeControlMode
virtual int writeControlMode(uint8_t id, uint8_t mode)=0
ttl_driver::AbstractStepperDriver::velocityUnit
virtual float velocityUnit() const =0
writeVelocityGoal: define the unit of the velocity in RPM
ttl_driver::AbstractMotorDriver::writeVelocityProfile
virtual int writeVelocityProfile(uint8_t id, const std::vector< uint32_t > &data_list)=0
abstract_stepper_driver.hpp
ttl_driver::AbstractMotorDriver::writePositionGoal
virtual int writePositionGoal(uint8_t id, uint32_t position)=0
ttl_driver
Definition: abstract_dxl_driver.hpp:30
ttl_driver::AbstractStepperDriver::writeSyncCmd
int writeSyncCmd(int type, const std::vector< uint8_t > &ids, const std::vector< uint32_t > &params) override
AbstractStepperDriver::writeSyncCmd.
Definition: abstract_stepper_driver.cpp:116
ttl_driver::AbstractStepperDriver::readConveyorVelocity
int readConveyorVelocity(uint8_t id, int32_t &velocity, int32_t &direction)
Returns the velocity of the conveyor in percentage.
Definition: abstract_stepper_driver.cpp:257
ttl_driver::AbstractMotorDriver
The XDriver class.
Definition: abstract_motor_driver.hpp:38
ttl_driver::AbstractMotorDriver::str
std::string str() const override
AbstractMotorDriver::str.
Definition: abstract_motor_driver.cpp:45
ttl_driver::AbstractMotorDriver::readVelocity
virtual int readVelocity(uint8_t id, uint32_t &present_velocity)=0
ttl_driver::AbstractMotorDriver::syncWriteVelocityGoal
virtual int syncWriteVelocityGoal(const std::vector< uint8_t > &id_list, const std::vector< uint32_t > &velocity_list)=0
ttl_driver::AbstractStepperDriver::startHoming
virtual int startHoming(uint8_t id)=0
ttl_driver::AbstractMotorDriver::writeTorquePercentage
virtual int writeTorquePercentage(uint8_t id, uint8_t torque_percentage)=0
ttl_driver::AbstractMotorDriver::syncWriteTorquePercentage
virtual int syncWriteTorquePercentage(const std::vector< uint8_t > &id_list, const std::vector< uint8_t > &torque_percentage_list)=0
ttl_driver::AbstractMotorDriver::writeVelocityGoal
virtual int writeVelocityGoal(uint8_t id, uint32_t velocity)=0


ttl_driver
Author(s): Clement Cocquempot
autogenerated on Fri Mar 6 2026 15:24:15