22 #include "driver_thread.h" 23 #include "servo_chain.h" 25 #include <utils/math/angle.h> 26 #include <core/threading/mutex_locker.h> 27 #include <core/threading/read_write_lock.h> 28 #include <core/threading/scoped_rwlock.h> 29 #include <core/threading/wait_condition.h> 30 #include <interfaces/DynamixelServoInterface.h> 31 #include <interfaces/LedInterface.h> 32 #include <interfaces/JointInterface.h> 33 #include <utils/misc/string_split.h> 53 std::string &cfg_prefix)
54 :
Thread(
"DynamixelDriverThread",
Thread::OPMODE_WAITFORWAKEUP),
57 set_name(
"DynamixelDriverThread(%s)", cfg_name.c_str());
59 cfg_prefix_ = cfg_prefix;
68 cfg_read_timeout_ms_ =
config->
get_uint((cfg_prefix_ +
"read_timeout_ms").c_str());
69 cfg_disc_timeout_ms_ =
config->
get_uint((cfg_prefix_ +
"discover_timeout_ms").c_str());
70 cfg_goto_zero_start_ =
config->
get_bool((cfg_prefix_ +
"goto_zero_start").c_str());
71 cfg_turn_off_ =
config->
get_bool((cfg_prefix_ +
"turn_off").c_str());
72 cfg_cw_compl_margin_ =
config->
get_uint((cfg_prefix_ +
"cw_compl_margin").c_str());
73 cfg_ccw_compl_margin_ =
config->
get_uint((cfg_prefix_ +
"ccw_compl_margin").c_str());
74 cfg_cw_compl_slope_ =
config->
get_uint((cfg_prefix_ +
"cw_compl_slope").c_str());
75 cfg_ccw_compl_slope_ =
config->
get_uint((cfg_prefix_ +
"ccw_compl_slope").c_str());
76 cfg_def_angle_margin_ =
config->
get_float((cfg_prefix_ +
"angle_margin").c_str());
77 cfg_enable_echo_fix_ =
config->
get_bool((cfg_prefix_ +
"enable_echo_fix").c_str());
78 cfg_enable_connection_stability_ =
config->
get_bool((cfg_prefix_ +
"enable_connection_stability").c_str());
79 cfg_autorecover_enabled_ =
config->
get_bool((cfg_prefix_ +
"autorecover_enabled").c_str());
80 cfg_autorecover_flags_ =
config->
get_uint((cfg_prefix_ +
"autorecover_flags").c_str());
81 cfg_torque_limit_ =
config->
get_float((cfg_prefix_ +
"torque_limit").c_str());
82 cfg_temperature_limit_ =
config->
get_uint((cfg_prefix_ +
"temperature_limit").c_str());
83 cfg_prevent_alarm_shutdown_ =
config->
get_bool((cfg_prefix_ +
"prevent_alarm_shutdown").c_str());
84 cfg_prevent_alarm_shutdown_threshold_ =
config->
get_float((cfg_prefix_ +
"prevent_alarm_shutdown_threshold").c_str());
85 cfg_min_voltage_ =
config->
get_float((cfg_prefix_ +
"min_voltage").c_str());
86 cfg_max_voltage_ =
config->
get_float((cfg_prefix_ +
"max_voltage").c_str());
87 cfg_servos_to_discover_ =
config->
get_uints((cfg_prefix_ +
"servos").c_str());
89 chain_ =
new DynamixelChain(cfg_device_.c_str(), cfg_read_timeout_ms_, cfg_enable_echo_fix_, cfg_enable_connection_stability_, cfg_min_voltage_, cfg_max_voltage_);
91 std::list<std::string> found_servos;
92 for (DynamixelChain::DeviceList::iterator i = devl.begin(); i != devl.end(); ++i) {
93 found_servos.push_back(std::to_string(*i));
102 cfg_name_.c_str(), *i);
105 cfg_name_.c_str(), *i);
108 cfg_name_.c_str(), *i);
119 s.move_pending =
false;
120 s.mode_set_pending =
false;
121 s.recover_pending =
false;
123 s.velo_pending =
false;
127 s.led_enable =
false;
128 s.led_disable =
false;
130 s.torque_limit = cfg_torque_limit_ * 0x3ff;
132 s.angle_margin = cfg_def_angle_margin_;
140 fresh_data_mutex_ =
new Mutex();
143 if (servos_.empty()) {
144 throw Exception(
"No servos found in chain %s", cfg_name_.c_str());
151 cfg_cw_compl_margin_, cfg_cw_compl_slope_,
152 cfg_ccw_compl_margin_, cfg_ccw_compl_slope_);
157 for (
auto &sp : servos_) {
158 unsigned int servo_id = sp.first;
159 Servo &s = sp.second;
170 unsigned int cw_limit, ccw_limit;
173 unsigned char cw_margin, cw_slope, ccw_margin, ccw_slope;
176 s.servo_if->set_model(chain_->
get_model(servo_id));
178 s.servo_if->set_cw_angle_limit(cw_limit);
179 s.servo_if->set_ccw_angle_limit(ccw_limit);
182 s.servo_if->set_mode(cw_limit == ccw_limit && cw_limit == 0 ?
"WHEEL" :
"JOINT");
183 s.servo_if->set_cw_slope(cw_slope);
184 s.servo_if->set_ccw_slope(ccw_slope);
185 s.servo_if->set_cw_margin(cw_margin);
186 s.servo_if->set_ccw_margin(ccw_margin);
187 s.servo_if->set_torque_limit(s.torque_limit);
188 s.servo_if->set_max_velocity(s.max_speed);
189 s.servo_if->set_enable_prevent_alarm_shutdown(cfg_prevent_alarm_shutdown_);
190 s.servo_if->set_autorecover_enabled(cfg_autorecover_enabled_);
193 s.servo_if->set_auto_timestamping(
false);
196 if ( cfg_goto_zero_start_ ) {
197 for (
auto &s : servos_) {
198 goto_angle_timed(s.first, 0., 3.0);
210 for (
auto &s : servos_) {
216 delete chain_rwlock_;
217 delete fresh_data_mutex_;
218 delete update_waitcond_;
221 for (
auto &s : servos_) {
228 cfg_name_.c_str(), s.first, e.
what());
247 if (has_fresh_data()) {
248 for (
auto &sp : servos_) {
249 unsigned int servo_id = sp.first;
250 Servo &s = sp.second;
253 float angle = get_angle(servo_id, time);
254 float vel = get_velocity(servo_id);
257 if (fabs(s.last_angle - angle) >=
deg2rad(0.5)) {
258 s.last_angle = angle;
260 angle = s.last_angle;
263 ScopedRWLock lock(chain_rwlock_, ScopedRWLock::LOCK_READ);
265 s.servo_if->set_timestamp(&s.time);
266 s.servo_if->set_position(chain_->
get_position(servo_id));
267 s.servo_if->set_speed(chain_->
get_speed(servo_id));
270 s.servo_if->set_load(chain_->
get_load(servo_id));
271 s.servo_if->set_voltage(chain_->
get_voltage(servo_id));
273 s.servo_if->set_punch(chain_->
get_punch(servo_id));
274 s.servo_if->set_angle(angle);
275 s.servo_if->set_velocity(vel);
277 s.servo_if->set_final(is_final(servo_id));
278 s.servo_if->set_velocity(get_velocity(servo_id));
281 if ((chain_->
get_load(servo_id) & 0x3ff) > (cfg_prevent_alarm_shutdown_threshold_ * chain_->
get_torque_limit(servo_id))) {
283 if (s.servo_if->is_enable_prevent_alarm_shutdown()) {
285 if (chain_->
get_load(servo_id) & 0x400) {
286 goto_angle(servo_id, get_angle(servo_id) + 0.001);
289 goto_angle(servo_id, get_angle(servo_id) - 0.001);
294 if (s.servo_if->is_autorecover_enabled() && chain_->
get_error(servo_id) & cfg_autorecover_flags_) {
296 s.recover_pending =
true;
299 unsigned char cur_error = chain_->
get_error(servo_id);
300 s.servo_if->set_error(s.servo_if->error() | cur_error);
306 s.joint_if->set_position(angle);
307 s.joint_if->set_velocity(vel);
318 for (
auto &sp : servos_) {
319 unsigned int servo_id = sp.first;
320 Servo &s = sp.second;
322 s.servo_if->set_final(is_final(servo_id));
324 while (! s.servo_if->msgq_empty() ) {
328 goto_angle(servo_id, msg->
angle());
329 s.servo_if->set_msgid(msg->
id());
330 s.servo_if->set_final(
false);
336 s.servo_if->set_msgid(msg->
id());
337 s.servo_if->set_final(
false);
347 if (msg->
velocity() > s.servo_if->max_velocity()) {
349 msg->
velocity(), s.servo_if->max_velocity());
351 set_velocity(servo_id, msg->
velocity());
361 s.servo_if->set_error(0);
369 set_mode(servo_id, msg->
mode());
373 set_speed(servo_id, msg->
speed());
381 s.recover_pending =
true;
385 s.recover_pending =
true;
391 s.servo_if->msgq_pop();
396 bool write_led_if =
false;
397 while (! s.led_if->msgq_empty() ) {
401 set_led_enabled(servo_id, (msg->
intensity() >= 0.5));
402 s.led_if->set_intensity((msg->
intensity() >= 0.5) ? LedInterface::ON : LedInterface::OFF);
404 set_led_enabled(servo_id,
true);
405 s.led_if->set_intensity(LedInterface::ON);
407 set_led_enabled(servo_id,
false);
408 s.led_if->set_intensity(LedInterface::OFF);
411 s.led_if->msgq_pop();
413 if (write_led_if) s.led_if->write();
422 std::map<unsigned int, Servo>::iterator si =
423 std::find_if(servos_.begin(), servos_.end(),
424 [interface](
const std::pair<unsigned int, Servo> &sp){
425 return (strcmp(sp.second.servo_if->uid(), interface->uid()) == 0);
427 if (si != servos_.end()) {
429 stop_motion(si->first);
432 stop_motion(si->first);
434 si->second.servo_if->msgq_flush();
449 DynamixelDriverThread::set_enabled(
unsigned int servo_id,
bool enabled)
451 if (servos_.find(servo_id) == servos_.end()) {
453 servo_id, cfg_name_.c_str());
457 Servo &s = servos_[servo_id];
477 DynamixelDriverThread::set_led_enabled(
unsigned int servo_id,
bool enabled)
479 if (servos_.find(servo_id) == servos_.end()) {
481 servo_id, cfg_name_.c_str());
485 Servo &s = servos_[servo_id];
490 s.led_disable =
false;
492 s.led_enable =
false;
493 s.led_disable =
true;
502 DynamixelDriverThread::stop_motion(
unsigned int servo_id)
504 if (servos_.find(servo_id) == servos_.end()) {
506 servo_id, cfg_name_.c_str());
510 float angle = get_angle(servo_id);
511 goto_angle(servo_id, angle);
519 DynamixelDriverThread::goto_angle(
unsigned int servo_id,
float angle)
521 if (servos_.find(servo_id) == servos_.end()) {
523 servo_id, cfg_name_.c_str());
527 Servo &s = servos_[servo_id];
531 s.target_angle = angle;
532 s.move_pending =
true;
543 DynamixelDriverThread::goto_angle_timed(
unsigned int servo_id,
float angle,
float time_sec)
545 if (servos_.find(servo_id) == servos_.end()) {
547 servo_id, cfg_name_.c_str());
550 Servo &s = servos_[servo_id];
552 s.target_angle = angle;
553 s.move_pending =
true;
555 float cangle = get_angle(servo_id);
556 float angle_diff = fabs(angle - cangle);
557 float req_angle_vel = angle_diff / time_sec;
559 if (req_angle_vel > s.max_speed) {
561 "angle speed of %f rad/s, which is greater than the maximum " 562 "of %f rad/s, reducing to max", angle, time_sec, req_angle_vel);
563 req_angle_vel = s.max_speed;
565 set_velocity(servo_id, req_angle_vel);
575 DynamixelDriverThread::set_velocity(
unsigned int servo_id,
float vel)
577 if (servos_.find(servo_id) == servos_.end()) {
579 servo_id, cfg_name_.c_str());
582 Servo &s = servos_[servo_id];
585 set_speed(servo_id, (
unsigned int) velo_tmp);
596 DynamixelDriverThread::set_speed(
unsigned int servo_id,
unsigned int speed)
598 if (servos_.find(servo_id) == servos_.end()) {
600 servo_id, cfg_name_.c_str());
603 Servo &s = servos_[servo_id];
608 s.velo_pending =
true;
611 "min: 0 max: %u des: %u",
621 DynamixelDriverThread::set_mode(
unsigned int servo_id,
unsigned int mode)
623 if (servos_.find(servo_id) == servos_.end()) {
625 servo_id, cfg_name_.c_str());
628 Servo &s = servos_[servo_id];
631 s.mode_set_pending =
true;
633 s.servo_if->set_mode(mode == DynamixelServoInterface::JOINT ?
"JOINT" :
"WHEEL");
640 DynamixelDriverThread::get_velocity(
unsigned int servo_id)
642 if (servos_.find(servo_id) == servos_.end()) {
644 servo_id, cfg_name_.c_str());
647 Servo &s = servos_[servo_id];
649 unsigned int velticks = chain_->
get_speed(servo_id);
660 DynamixelDriverThread::set_margin(
unsigned int servo_id,
float angle_margin)
662 if (servos_.find(servo_id) == servos_.end()) {
664 servo_id, cfg_name_.c_str());
667 Servo &s = servos_[servo_id];
668 if (angle_margin > 0.0) s.angle_margin = angle_margin;
675 DynamixelDriverThread::get_angle(
unsigned int servo_id)
677 if (servos_.find(servo_id) == servos_.end()) {
679 servo_id, cfg_name_.c_str());
683 ScopedRWLock lock(chain_rwlock_, ScopedRWLock::LOCK_READ);
695 DynamixelDriverThread::get_angle(
unsigned int servo_id,
698 if (servos_.find(servo_id) == servos_.end()) {
700 servo_id, cfg_name_.c_str());
703 Servo &s = servos_[servo_id];
706 return get_angle(servo_id);
714 DynamixelDriverThread::is_final(
unsigned int servo_id)
716 if (servos_.find(servo_id) == servos_.end()) {
718 servo_id, cfg_name_.c_str());
721 Servo &s = servos_[servo_id];
723 float angle = get_angle(servo_id);
725 ScopedRWLock lock(chain_rwlock_, ScopedRWLock::LOCK_READ);
727 return ( (fabs(angle - s.target_angle) <= s.angle_margin) ||
736 DynamixelDriverThread::is_enabled(
unsigned int servo_id)
747 DynamixelDriverThread::has_fresh_data()
751 bool rv = fresh_data_;
760 for (
auto &sp : servos_) {
761 unsigned int servo_id = sp.first;
762 Servo &s = sp.second;
764 s.value_rwlock->lock_for_write();
766 s.value_rwlock->unlock();
770 if (s.led_enable || s.led_disable || s.velo_pending || s.move_pending || s.mode_set_pending || s.recover_pending) usleep(3000);
771 }
else if (s.disable) {
772 s.value_rwlock->lock_for_write();
774 s.value_rwlock->unlock();
777 if (s.led_enable || s.led_disable || s.velo_pending || s.move_pending || s.mode_set_pending || s.recover_pending) usleep(3000);
781 s.value_rwlock->lock_for_write();
782 s.led_enable =
false;
783 s.value_rwlock->unlock();
786 if (s.velo_pending || s.move_pending || s.mode_set_pending || s.recover_pending) usleep(3000);
787 }
else if (s.led_disable) {
788 s.value_rwlock->lock_for_write();
789 s.led_disable =
false;
790 s.value_rwlock->unlock();
793 if (s.velo_pending || s.move_pending || s.mode_set_pending || s.recover_pending) usleep(3000);
796 if (s.velo_pending) {
797 s.value_rwlock->lock_for_write();
798 s.velo_pending =
false;
799 unsigned int vel = s.vel;
800 s.value_rwlock->unlock();
803 if (s.move_pending || s.mode_set_pending || s.recover_pending) usleep(3000);
806 if (s.move_pending) {
807 s.value_rwlock->lock_for_write();
808 s.move_pending =
false;
809 float target_angle = s.target_angle;
810 s.value_rwlock->unlock();
811 exec_goto_angle(servo_id, target_angle);
812 if (s.mode_set_pending || s.recover_pending) usleep(3000);
815 if (s.mode_set_pending) {
816 s.value_rwlock->lock_for_write();
817 s.mode_set_pending =
false;
818 exec_set_mode(servo_id, s.new_mode);
819 s.value_rwlock->unlock();
820 if (s.recover_pending) usleep(3000);
823 if (s.recover_pending) {
824 s.value_rwlock->lock_for_write();
825 s.recover_pending =
false;
827 s.value_rwlock->unlock();
831 ScopedRWLock lock(chain_rwlock_, ScopedRWLock::LOCK_READ);
855 DynamixelDriverThread::exec_goto_angle(
unsigned int servo_id,
float angle_rad)
857 unsigned int pos_min = 0, pos_max = 0;
863 if ( (pos < 0) || ((
unsigned int)pos < pos_min) || ((
unsigned int)pos > pos_max) ) {
865 pos_min, pos_max, pos);
878 DynamixelDriverThread::exec_set_mode(
unsigned int servo_id,
unsigned int new_mode)
880 if (new_mode == DynamixelServoInterface::JOINT) {
884 else if (new_mode == DynamixelServoInterface::WHEEL) {
901 DynamixelDriverThread::wait_for_fresh_data()
903 update_waitcond_->
wait();
void get_compliance_values(unsigned char id, unsigned char &cw_margin, unsigned char &cw_slope, unsigned char &ccw_margin, unsigned char &ccw_slope, bool refresh=false)
Get compliance values.
TurnOffMessage Fawkes BlackBoard Interface Message.
std::list< unsigned char > DeviceList
List of servo IDs.
unsigned int get_speed(unsigned char id, bool refresh=false)
Get current speed.
Class to access a chain of Robotis dynamixel servos.
unsigned char get_alarm_shutdown(unsigned char id, bool refresh=false)
Get shutdown on alarm state.
Wait until a given condition holds.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
unsigned int id() const
Get message ID.
SetAutorecoverEnabledMessage Fawkes BlackBoard Interface Message.
bool is_torque_enabled(unsigned char id, bool refresh=false)
Check if torque is enabled.
virtual void init()
Initialize the thread.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
static const unsigned char BROADCAST_ID
BROADCAST_ID.
float get_max_supported_speed(unsigned char id, bool refresh=false)
Get maximum supported speed.
bool is_enabled() const
Get enabled value.
void set_temperature_limit(unsigned char id, unsigned char temp_limit)
Set temperature limit.
bool is_autorecover_enabled() const
Get autorecover_enabled value.
float intensity() const
Get intensity value.
Fawkes library namespace.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
const char * get_model(unsigned char id, bool refresh=false)
Get model string.
unsigned int get_position(unsigned char id, bool refresh=false)
Get current position.
void wake_all()
Wake up all waiting threads.
virtual bool bb_interface_message_received(fawkes::Interface *interface, fawkes::Message *message)
BlackBoard message received notification.
std::string str_join(const InputIterator &first, const InputIterator &last, char delim='/')
Join list of strings string using given delimiter.
unsigned int get_max_torque(unsigned char id, bool refresh=false)
Get maximum torque.
SetTorqueLimitMessage Fawkes BlackBoard Interface Message.
unsigned int get_model_number(unsigned char id, bool refresh=false)
Get model.
unsigned int get_goal_speed(unsigned char id, bool refresh=false)
Get goal speed.
uint8_t mode() const
Get mode value.
A class for handling time.
float time_sec() const
Get time_sec value.
virtual void finalize()
Finalize the thread.
unsigned char get_error(unsigned char id)
Get error flags set by the servo.
virtual const char * what() const
Get primary string.
unsigned char get_voltage(unsigned char id, bool refresh=false)
Get current voltage.
virtual void unregister_listener(BlackBoardInterfaceListener *listener)
Unregister BB interface listener.
Thread class encapsulation of pthreads.
void set_angle_limits(unsigned char id, unsigned int cw_limit, unsigned int ccw_limit)
Set angle limits.
SetMarginMessage Fawkes BlackBoard Interface Message.
Base class for all Fawkes BlackBoard interfaces.
static const float RAD_PER_POS_TICK
RAD_PER_POS_TICK.
Logger * logger
This is the Logger member used to access the logger.
ResetRawErrorMessage Fawkes BlackBoard Interface Message.
void exec_act()
Process commands.
StopMessage Fawkes BlackBoard Interface Message.
SetModeMessage Fawkes BlackBoard Interface Message.
void get_angle_limits(unsigned char id, unsigned int &cw_limit, unsigned int &ccw_limit, bool refresh=false)
Get angle limits.
unsigned int get_goal_position(unsigned char id, bool refresh=false)
Get goal position.
FlushMessage Fawkes BlackBoard Interface Message.
void read_table_values(unsigned char id)
Read all table values for given servo.
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
bool is_moving(unsigned char id, bool refresh=false)
Check if servo is moving.
void goto_position(unsigned char id, unsigned int value)
Move servo to specified position.
uint32_t torque_limit() const
Get torque_limit value.
void wakeup()
Wake up thread.
void set_name(const char *format,...)
Set name of thread.
Base class for exceptions in Fawkes.
static const unsigned char SRL_RESPOND_READ
SRL_RESPOND_READ.
void set_autorecover_enabled(const bool new_autorecover_enabled)
Set autorecover_enabled value.
virtual std::vector< unsigned int > get_uints(const char *path)=0
Get list of values from configuration which is of type unsigned int.
bool is_enable_prevent_alarm_shutdown() const
Get enable_prevent_alarm_shutdown value.
static const float POS_TICKS_PER_RAD
POS_TICKS_PER_RAD.
uint16_t speed() const
Get speed value.
float angle() const
Get angle value.
Read/write lock to allow multiple readers but only a single writer on the resource at a time...
void set_led_enabled(unsigned char id, bool enabled)
Turn LED on or off.
virtual Interface * open_for_writing_f(const char *interface_type, const char *identifier,...)
Open interface for writing with identifier format string.
TimedGotoMessage Fawkes BlackBoard Interface Message.
SetIntensityMessage Fawkes BlackBoard Interface Message.
const char * name() const
Get name of thread.
unsigned int get_load(unsigned char id, bool refresh=false)
Get current load.
void set_compliance_values(unsigned char id, unsigned char cw_margin, unsigned char cw_slope, unsigned char ccw_margin, unsigned char ccw_slope)
Set compliance values.
SetEnabledMessage Fawkes BlackBoard Interface Message.
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
virtual void log_error(const char *component, const char *format,...)=0
Log error message.
unsigned int get_punch(unsigned char id, bool refresh=false)
Get punch.
void wait()
Wait for the condition forever.
void set_status_return_level(unsigned char id, unsigned char status_return_level)
Set status return level.
LedInterface Fawkes BlackBoard Interface.
static const unsigned int CENTER_POSITION
CENTER_POSITION.
DeviceList discover(unsigned int total_timeout_ms=50, const std::vector< unsigned int > servos=std::vector< unsigned int >())
Discover devices on the bus.
virtual void loop()
Code to execute in the thread.
float velocity() const
Get velocity value.
SetSpeedMessage Fawkes BlackBoard Interface Message.
void set_enable_prevent_alarm_shutdown(const bool new_enable_prevent_alarm_shutdown)
Set enable_prevent_alarm_shutdown value.
virtual void log_debug(const char *component, const char *format,...)=0
Log debug message.
void exec_sensor()
Update sensor values as necessary.
GotoMessage Fawkes BlackBoard Interface Message.
TurnOnMessage Fawkes BlackBoard Interface Message.
float angle_margin() const
Get angle_margin value.
DynamixelServoInterface Fawkes BlackBoard Interface.
void set_torque_enabled(unsigned char id, bool enabled)
Enable or disable torque.
JointInterface Fawkes BlackBoard Interface.
virtual unsigned int get_uint(const char *path)=0
Get value from configuration which is of type unsigned int.
Mutex mutual exclusion lock.
float deg2rad(float deg)
Convert an angle given in degrees to radians.
void set_goal_speed(unsigned char id, unsigned int goal_speed)
Set goal speed.
unsigned char get_temperature_limit(unsigned char id, bool refresh=false)
Get temperature limit.
unsigned int get_torque_limit(unsigned char id, bool refresh=false)
Get torque limit.
DynamixelDriverThread(std::string &cfg_name, std::string &cfg_prefix)
Constructor.
void set_torque_limit(unsigned char id, unsigned int torque_limit)
Set torque limit.
Configuration * config
This is the Configuration member used to access the configuration.
RecoverMessage Fawkes BlackBoard Interface Message.
void bbil_add_message_interface(Interface *interface)
Add an interface to the message received watch list.
float angle() const
Get angle value.
virtual float get_float(const char *path)=0
Get value from configuration which is of type float.
static const unsigned int MAX_SPEED
MAX_SPEED.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
BlackBoard interface listener.
unsigned char get_temperature(unsigned char id, bool refresh=false)
Get temperature.
BlackBoard * blackboard
This is the BlackBoard instance you can use to interact with the BlackBoard.
SetVelocityMessage Fawkes BlackBoard Interface Message.
SetPreventAlarmShutdownMessage Fawkes BlackBoard Interface Message.
virtual void close(Interface *interface)=0
Close interface.