22 #include "driver_thread.h"
24 #include "servo_chain.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/JointInterface.h>
32 #include <interfaces/LedInterface.h>
33 #include <utils/math/angle.h>
34 #include <utils/misc/string_split.h>
54 :
Thread(
"DynamixelDriverThread",
Thread::OPMODE_WAITFORWAKEUP),
57 set_name(
"DynamixelDriverThread(%s)", cfg_name.c_str());
59 cfg_prefix_ = cfg_prefix;
67 cfg_read_timeout_ms_ =
config->
get_uint((cfg_prefix_ +
"read_timeout_ms").c_str());
68 cfg_disc_timeout_ms_ =
config->
get_uint((cfg_prefix_ +
"discover_timeout_ms").c_str());
69 cfg_goto_zero_start_ =
config->
get_bool((cfg_prefix_ +
"goto_zero_start").c_str());
70 cfg_turn_off_ =
config->
get_bool((cfg_prefix_ +
"turn_off").c_str());
71 cfg_cw_compl_margin_ =
config->
get_uint((cfg_prefix_ +
"cw_compl_margin").c_str());
72 cfg_ccw_compl_margin_ =
config->
get_uint((cfg_prefix_ +
"ccw_compl_margin").c_str());
73 cfg_cw_compl_slope_ =
config->
get_uint((cfg_prefix_ +
"cw_compl_slope").c_str());
74 cfg_ccw_compl_slope_ =
config->
get_uint((cfg_prefix_ +
"ccw_compl_slope").c_str());
75 cfg_def_angle_margin_ =
config->
get_float((cfg_prefix_ +
"angle_margin").c_str());
76 cfg_enable_echo_fix_ =
config->
get_bool((cfg_prefix_ +
"enable_echo_fix").c_str());
77 cfg_enable_connection_stability_ =
78 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_ =
85 config->
get_float((cfg_prefix_ +
"prevent_alarm_shutdown_threshold").c_str());
86 cfg_min_voltage_ =
config->
get_float((cfg_prefix_ +
"min_voltage").c_str());
87 cfg_max_voltage_ =
config->
get_float((cfg_prefix_ +
"max_voltage").c_str());
88 cfg_servos_to_discover_ =
config->
get_uints((cfg_prefix_ +
"servos").c_str());
89 cfg_enable_verbose_output_ =
config->
get_bool((cfg_prefix_ +
"enable_verbose_output").c_str());
94 cfg_enable_connection_stability_,
98 std::list<std::string> found_servos;
99 for (DynamixelChain::DeviceList::iterator i = devl.begin(); i != devl.end(); ++i) {
100 found_servos.push_back(std::to_string(*i));
124 s.move_pending =
false;
125 s.mode_set_pending =
false;
126 s.recover_pending =
false;
128 s.velo_pending =
false;
132 s.led_enable =
false;
133 s.led_disable =
false;
135 s.torque_limit = cfg_torque_limit_ * 0x3ff;
137 s.angle_margin = cfg_def_angle_margin_;
145 fresh_data_mutex_ =
new Mutex();
148 if (servos_.empty()) {
149 throw Exception(
"No servos found in chain %s", cfg_name_.c_str());
156 cfg_cw_compl_margin_,
158 cfg_ccw_compl_margin_,
159 cfg_ccw_compl_slope_);
164 for (
auto &sp : servos_) {
165 unsigned int servo_id = sp.first;
166 Servo & s = sp.second;
175 unsigned int cw_limit, ccw_limit;
178 unsigned char cw_margin, cw_slope, ccw_margin, ccw_slope;
181 s.servo_if->set_model(chain_->
get_model(servo_id));
183 s.servo_if->set_cw_angle_limit(cw_limit);
184 s.servo_if->set_ccw_angle_limit(ccw_limit);
187 s.servo_if->set_mode(cw_limit == ccw_limit && cw_limit == 0 ?
"WHEEL" :
"JOINT");
188 s.servo_if->set_cw_slope(cw_slope);
189 s.servo_if->set_ccw_slope(ccw_slope);
190 s.servo_if->set_cw_margin(cw_margin);
191 s.servo_if->set_ccw_margin(ccw_margin);
192 s.servo_if->set_torque_limit(s.torque_limit);
193 s.servo_if->set_max_velocity(s.max_speed);
194 s.servo_if->set_enable_prevent_alarm_shutdown(cfg_prevent_alarm_shutdown_);
195 s.servo_if->set_autorecover_enabled(cfg_autorecover_enabled_);
198 s.servo_if->set_auto_timestamping(
false);
201 if (cfg_goto_zero_start_) {
202 for (
auto &s : servos_) {
203 goto_angle_timed(s.first, 0., 3.0);
215 for (
auto &s : servos_) {
221 delete chain_rwlock_;
222 delete fresh_data_mutex_;
223 delete update_waitcond_;
226 for (
auto &s : servos_) {
233 name(),
"Failed to turn of servo %s:%u: %s", cfg_name_.c_str(), s.first, e.
what());
251 if (has_fresh_data()) {
252 for (
auto &sp : servos_) {
253 unsigned int servo_id = sp.first;
254 Servo & s = sp.second;
257 float angle = get_angle(servo_id, time);
258 float vel = get_velocity(servo_id);
261 if (fabs(s.last_angle - angle) >=
deg2rad(0.5)) {
262 s.last_angle = angle;
264 angle = s.last_angle;
267 ScopedRWLock lock(chain_rwlock_, ScopedRWLock::LOCK_READ);
269 s.servo_if->set_timestamp(&s.time);
270 s.servo_if->set_position(chain_->
get_position(servo_id));
271 s.servo_if->set_speed(chain_->
get_speed(servo_id));
274 s.servo_if->set_load(chain_->
get_load(servo_id));
275 s.servo_if->set_voltage(chain_->
get_voltage(servo_id));
277 s.servo_if->set_punch(chain_->
get_punch(servo_id));
278 s.servo_if->set_angle(angle);
279 s.servo_if->set_velocity(vel);
281 s.servo_if->set_final(is_final(servo_id));
282 s.servo_if->set_velocity(get_velocity(servo_id));
285 if (s.servo_if->is_enable_prevent_alarm_shutdown()) {
286 if ((chain_->
get_load(servo_id) & 0x3ff)
287 > (cfg_prevent_alarm_shutdown_threshold_ * chain_->
get_torque_limit(servo_id))) {
289 "Servo with ID: %d is in overload condition: torque_limit: %d, load: %d",
292 chain_->
get_load(servo_id) & 0x3ff);
294 if (chain_->
get_load(servo_id) & 0x400) {
295 goto_angle(servo_id, get_angle(servo_id) + 0.001);
297 goto_angle(servo_id, get_angle(servo_id) - 0.001);
302 if (s.servo_if->is_autorecover_enabled()
303 && chain_->
get_error(servo_id) & cfg_autorecover_flags_) {
305 s.recover_pending =
true;
308 unsigned char cur_error = chain_->
get_error(servo_id);
309 s.servo_if->set_error(s.servo_if->error() | cur_error);
315 s.joint_if->set_position(angle);
316 s.joint_if->set_velocity(vel);
326 for (
auto &sp : servos_) {
327 unsigned int servo_id = sp.first;
328 Servo & s = sp.second;
330 s.servo_if->set_final(is_final(servo_id));
332 while (!s.servo_if->msgq_empty()) {
336 goto_angle(servo_id, msg->
angle());
337 s.servo_if->set_msgid(msg->
id());
338 s.servo_if->set_final(
false);
344 s.servo_if->set_msgid(msg->
id());
345 s.servo_if->set_final(
false);
355 if (msg->
velocity() > s.servo_if->max_velocity()) {
357 "Desired velocity %f too high, max is %f",
359 s.servo_if->max_velocity());
361 set_velocity(servo_id, msg->
velocity());
371 s.servo_if->set_error(0);
373 }
else if (s.servo_if
380 set_mode(servo_id, msg->
mode());
384 set_speed(servo_id, msg->
speed());
386 }
else if (s.servo_if
393 s.recover_pending =
true;
397 s.recover_pending =
true;
403 s.servo_if->msgq_pop();
408 bool write_led_if =
false;
409 while (!s.led_if->msgq_empty()) {
413 set_led_enabled(servo_id, (msg->
intensity() >= 0.5));
414 s.led_if->set_intensity((msg->
intensity() >= 0.5) ? LedInterface::ON : LedInterface::OFF);
416 set_led_enabled(servo_id,
true);
417 s.led_if->set_intensity(LedInterface::ON);
419 set_led_enabled(servo_id,
false);
420 s.led_if->set_intensity(LedInterface::OFF);
423 s.led_if->msgq_pop();
434 std::map<unsigned int, Servo>::iterator si =
435 std::find_if(servos_.begin(),
437 [interface](
const std::pair<unsigned int, Servo> &sp) {
438 return (strcmp(sp.second.servo_if->uid(), interface->uid()) == 0);
440 if (si != servos_.end()) {
442 stop_motion(si->first);
445 stop_motion(si->first);
446 if (cfg_enable_verbose_output_) {
447 logger->
log_info(name(),
"Flushing message queue");
449 si->second.servo_if->msgq_flush();
452 if (cfg_enable_verbose_output_) {
453 logger->
log_info(name(),
"Received message of type %s, enqueueing", message->type());
465 DynamixelDriverThread::set_enabled(
unsigned int servo_id,
bool enabled)
467 if (servos_.find(servo_id) == servos_.end()) {
469 "No servo with ID %u in chain %s, cannot set LED",
475 Servo &s = servos_[servo_id];
494 DynamixelDriverThread::set_led_enabled(
unsigned int servo_id,
bool enabled)
496 if (servos_.find(servo_id) == servos_.end()) {
498 "No servo with ID %u in chain %s, cannot set LED",
504 Servo &s = servos_[servo_id];
509 s.led_disable =
false;
511 s.led_enable =
false;
512 s.led_disable =
true;
520 DynamixelDriverThread::stop_motion(
unsigned int servo_id)
522 if (servos_.find(servo_id) == servos_.end()) {
524 "No servo with ID %u in chain %s, cannot set LED",
530 float angle = get_angle(servo_id);
531 goto_angle(servo_id, angle);
538 DynamixelDriverThread::goto_angle(
unsigned int servo_id,
float angle)
540 if (servos_.find(servo_id) == servos_.end()) {
542 "No servo with ID %u in chain %s, cannot set LED",
548 Servo &s = servos_[servo_id];
552 s.target_angle = angle;
553 s.move_pending =
true;
563 DynamixelDriverThread::goto_angle_timed(
unsigned int servo_id,
float angle,
float time_sec)
565 if (servos_.find(servo_id) == servos_.end()) {
567 "No servo with ID %u in chain %s, cannot set LED",
572 Servo &s = servos_[servo_id];
574 s.target_angle = angle;
575 s.move_pending =
true;
577 float cangle = get_angle(servo_id);
578 float angle_diff = fabs(angle - cangle);
579 float req_angle_vel = angle_diff / time_sec;
581 if (req_angle_vel > s.max_speed) {
583 "Requested move to %f in %f sec requires a "
584 "angle speed of %f rad/s, which is greater than the maximum "
585 "of %f rad/s, reducing to max",
590 req_angle_vel = s.max_speed;
592 set_velocity(servo_id, req_angle_vel);
601 DynamixelDriverThread::set_velocity(
unsigned int servo_id,
float vel)
603 if (servos_.find(servo_id) == servos_.end()) {
605 "No servo with ID %u in chain %s, cannot set velocity",
610 Servo &s = servos_[servo_id];
613 set_speed(servo_id, (
unsigned int)velo_tmp);
622 DynamixelDriverThread::set_speed(
unsigned int servo_id,
unsigned int speed)
624 if (servos_.find(servo_id) == servos_.end()) {
626 "No servo with ID %u in chain %s, cannot set speed",
631 Servo &s = servos_[servo_id];
636 s.velo_pending =
true;
639 "Calculated velocity value out of bounds, "
640 "min: 0 max: %u des: %u",
650 DynamixelDriverThread::set_mode(
unsigned int servo_id,
unsigned int mode)
652 if (servos_.find(servo_id) == servos_.end()) {
654 "No servo with ID %u in chain %s, cannot set mode",
659 Servo &s = servos_[servo_id];
662 s.mode_set_pending =
true;
664 s.servo_if->set_mode(mode == DynamixelServoInterface::JOINT ?
"JOINT" :
"WHEEL");
670 DynamixelDriverThread::get_velocity(
unsigned int servo_id)
672 if (servos_.find(servo_id) == servos_.end()) {
674 "No servo with ID %u in chain %s, cannot set velocity",
679 Servo &s = servos_[servo_id];
681 unsigned int velticks = chain_->
get_speed(servo_id);
690 DynamixelDriverThread::set_margin(
unsigned int servo_id,
float angle_margin)
692 if (servos_.find(servo_id) == servos_.end()) {
694 "No servo with ID %u in chain %s, cannot set velocity",
699 Servo &s = servos_[servo_id];
700 if (angle_margin > 0.0)
701 s.angle_margin = angle_margin;
707 DynamixelDriverThread::get_angle(
unsigned int servo_id)
709 if (servos_.find(servo_id) == servos_.end()) {
711 "No servo with ID %u in chain %s, cannot set velocity",
717 ScopedRWLock lock(chain_rwlock_, ScopedRWLock::LOCK_READ);
728 DynamixelDriverThread::get_angle(
unsigned int servo_id,
fawkes::Time &time)
730 if (servos_.find(servo_id) == servos_.end()) {
732 "No servo with ID %u in chain %s, cannot set velocity",
737 Servo &s = servos_[servo_id];
740 return get_angle(servo_id);
747 DynamixelDriverThread::is_final(
unsigned int servo_id)
749 if (servos_.find(servo_id) == servos_.end()) {
751 "No servo with ID %u in chain %s, cannot set velocity",
756 Servo &s = servos_[servo_id];
758 float angle = get_angle(servo_id);
760 ScopedRWLock lock(chain_rwlock_, ScopedRWLock::LOCK_READ);
762 return ((fabs(angle - s.target_angle) <= s.angle_margin) || (!chain_->
is_moving(servo_id)));
769 DynamixelDriverThread::is_enabled(
unsigned int servo_id)
779 DynamixelDriverThread::has_fresh_data()
783 bool rv = fresh_data_;
791 for (
auto &sp : servos_) {
792 unsigned int servo_id = sp.first;
793 Servo & s = sp.second;
795 s.value_rwlock->lock_for_write();
797 s.value_rwlock->unlock();
801 if (s.led_enable || s.led_disable || s.velo_pending || s.move_pending || s.mode_set_pending
802 || s.recover_pending)
804 }
else if (s.disable) {
805 s.value_rwlock->lock_for_write();
807 s.value_rwlock->unlock();
810 if (s.led_enable || s.led_disable || s.velo_pending || s.move_pending || s.mode_set_pending
811 || s.recover_pending)
816 s.value_rwlock->lock_for_write();
817 s.led_enable =
false;
818 s.value_rwlock->unlock();
821 if (s.velo_pending || s.move_pending || s.mode_set_pending || s.recover_pending)
823 }
else if (s.led_disable) {
824 s.value_rwlock->lock_for_write();
825 s.led_disable =
false;
826 s.value_rwlock->unlock();
829 if (s.velo_pending || s.move_pending || s.mode_set_pending || s.recover_pending)
833 if (s.velo_pending) {
834 s.value_rwlock->lock_for_write();
835 s.velo_pending =
false;
836 unsigned int vel = s.vel;
837 s.value_rwlock->unlock();
840 if (s.move_pending || s.mode_set_pending || s.recover_pending)
844 if (s.move_pending) {
845 s.value_rwlock->lock_for_write();
846 s.move_pending =
false;
847 float target_angle = s.target_angle;
848 s.value_rwlock->unlock();
849 exec_goto_angle(servo_id, target_angle);
850 if (s.mode_set_pending || s.recover_pending)
854 if (s.mode_set_pending) {
855 s.value_rwlock->lock_for_write();
856 s.mode_set_pending =
false;
857 exec_set_mode(servo_id, s.new_mode);
858 s.value_rwlock->unlock();
859 if (s.recover_pending)
863 if (s.recover_pending) {
864 s.value_rwlock->lock_for_write();
865 s.recover_pending =
false;
867 s.value_rwlock->unlock();
871 ScopedRWLock lock(chain_rwlock_, ScopedRWLock::LOCK_READ);
894 DynamixelDriverThread::exec_goto_angle(
unsigned int servo_id,
float angle_rad)
896 unsigned int pos_min = 0, pos_max = 0;
902 if ((pos < 0) || ((
unsigned int)pos < pos_min) || ((
unsigned int)pos > pos_max)) {
904 name(),
"Position out of bounds, min: %u max: %u des: %i", pos_min, pos_max, pos);
916 DynamixelDriverThread::exec_set_mode(
unsigned int servo_id,
unsigned int new_mode)
918 if (new_mode == DynamixelServoInterface::JOINT) {
921 }
else if (new_mode == DynamixelServoInterface::WHEEL) {
935 DynamixelDriverThread::wait_for_fresh_data()
937 update_waitcond_->
wait();
Class to access a chain of Robotis dynamixel servos.
void set_goal_speed(unsigned char id, unsigned int goal_speed)
Set goal speed.
void set_angle_limits(unsigned char id, unsigned int cw_limit, unsigned int ccw_limit)
Set angle limits.
unsigned char get_voltage(unsigned char id, bool refresh=false)
Get current voltage.
std::list< unsigned char > DeviceList
List of servo IDs.
static const unsigned char SRL_RESPOND_READ
SRL_RESPOND_READ.
void set_status_return_level(unsigned char id, unsigned char status_return_level)
Set status return level.
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.
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.
DeviceList discover(unsigned int total_timeout_ms=50, const std::vector< unsigned int > &servos=std::vector< unsigned int >())
Discover devices on the bus.
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.
void set_torque_limit(unsigned char id, unsigned int torque_limit)
Set torque limit.
unsigned char get_temperature_limit(unsigned char id, bool refresh=false)
Get temperature limit.
unsigned int get_max_torque(unsigned char id, bool refresh=false)
Get maximum torque.
void read_table_values(unsigned char id)
Read all table values for given servo.
static const unsigned int CENTER_POSITION
CENTER_POSITION.
unsigned int get_position(unsigned char id, bool refresh=false)
Get current position.
void get_angle_limits(unsigned char id, unsigned int &cw_limit, unsigned int &ccw_limit, bool refresh=false)
Get angle limits.
void goto_position(unsigned char id, unsigned int value)
Move servo to specified position.
unsigned int get_punch(unsigned char id, bool refresh=false)
Get punch.
void set_torque_enabled(unsigned char id, bool enabled)
Enable or disable torque.
float get_max_supported_speed(unsigned char id, bool refresh=false)
Get maximum supported speed.
static const unsigned int MAX_SPEED
MAX_SPEED.
static const float POS_TICKS_PER_RAD
POS_TICKS_PER_RAD.
static const float RAD_PER_POS_TICK
RAD_PER_POS_TICK.
unsigned int get_speed(unsigned char id, bool refresh=false)
Get current speed.
unsigned int get_goal_position(unsigned char id, bool refresh=false)
Get goal position.
unsigned char get_error(unsigned char id)
Get error flags set by the servo.
bool is_moving(unsigned char id, bool refresh=false)
Check if servo is moving.
void set_led_enabled(unsigned char id, bool enabled)
Turn LED on or off.
unsigned char get_temperature(unsigned char id, bool refresh=false)
Get temperature.
static const unsigned char BROADCAST_ID
BROADCAST_ID.
void set_temperature_limit(unsigned char id, unsigned char temp_limit)
Set temperature limit.
bool is_torque_enabled(unsigned char id, bool refresh=false)
Check if torque is enabled.
const char * get_model(unsigned char id, bool refresh=false)
Get model string.
unsigned char get_alarm_shutdown(unsigned char id, bool refresh=false)
Get shutdown on alarm state.
unsigned int get_torque_limit(unsigned char id, bool refresh=false)
Get torque limit.
unsigned int get_load(unsigned char id, bool refresh=false)
Get current load.
virtual void finalize()
Finalize the thread.
DynamixelDriverThread(std::string &cfg_name, std::string &cfg_prefix)
Constructor.
void exec_sensor()
Update sensor values as necessary.
virtual void init()
Initialize the thread.
virtual void loop()
Code to execute in the thread.
virtual bool bb_interface_message_received(fawkes::Interface *interface, fawkes::Message *message) noexcept
BlackBoard message received notification.
void exec_act()
Process commands.
BlackBoard * blackboard
This is the BlackBoard instance you can use to interact with the BlackBoard.
BlackBoard interface listener.
void bbil_add_message_interface(Interface *interface)
Add an interface to the message received watch list.
virtual void unregister_listener(BlackBoardInterfaceListener *listener)
Unregister BB interface listener.
virtual Interface * open_for_writing_f(const char *interface_type, const char *identifier,...)
Open interface for writing with identifier format string.
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
virtual void close(Interface *interface)=0
Close interface.
Configuration * config
This is the Configuration member used to access the configuration.
virtual unsigned int get_uint(const char *path)=0
Get value from configuration which is of type unsigned int.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
virtual float get_float(const char *path)=0
Get value from configuration which is of type float.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
virtual std::vector< unsigned int > get_uints(const char *path)=0
Get list of values from configuration which is of type unsigned int.
FlushMessage Fawkes BlackBoard Interface Message.
GotoMessage Fawkes BlackBoard Interface Message.
float angle() const
Get angle value.
RecoverMessage Fawkes BlackBoard Interface Message.
ResetRawErrorMessage Fawkes BlackBoard Interface Message.
SetAutorecoverEnabledMessage Fawkes BlackBoard Interface Message.
void set_autorecover_enabled(const bool new_autorecover_enabled)
Set autorecover_enabled value.
bool is_autorecover_enabled() const
Get autorecover_enabled value.
SetEnabledMessage Fawkes BlackBoard Interface Message.
bool is_enabled() const
Get enabled value.
SetMarginMessage Fawkes BlackBoard Interface Message.
float angle_margin() const
Get angle_margin value.
SetModeMessage Fawkes BlackBoard Interface Message.
uint8_t mode() const
Get mode value.
SetPreventAlarmShutdownMessage Fawkes BlackBoard Interface Message.
bool is_enable_prevent_alarm_shutdown() const
Get enable_prevent_alarm_shutdown value.
void set_enable_prevent_alarm_shutdown(const bool new_enable_prevent_alarm_shutdown)
Set enable_prevent_alarm_shutdown value.
SetSpeedMessage Fawkes BlackBoard Interface Message.
uint16_t speed() const
Get speed value.
SetTorqueLimitMessage Fawkes BlackBoard Interface Message.
uint32_t torque_limit() const
Get torque_limit value.
SetVelocityMessage Fawkes BlackBoard Interface Message.
float velocity() const
Get velocity value.
StopMessage Fawkes BlackBoard Interface Message.
TimedGotoMessage Fawkes BlackBoard Interface Message.
float time_sec() const
Get time_sec value.
float angle() const
Get angle value.
DynamixelServoInterface Fawkes BlackBoard Interface.
Base class for exceptions in Fawkes.
virtual const char * what() const noexcept
Get primary string.
Base class for all Fawkes BlackBoard interfaces.
JointInterface Fawkes BlackBoard Interface.
SetIntensityMessage Fawkes BlackBoard Interface Message.
float intensity() const
Get intensity value.
TurnOffMessage Fawkes BlackBoard Interface Message.
TurnOnMessage Fawkes BlackBoard Interface Message.
LedInterface Fawkes BlackBoard Interface.
virtual void log_debug(const char *component, const char *format,...)=0
Log debug 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.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
Logger * logger
This is the Logger member used to access the logger.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
unsigned int id() const
Get message ID.
virtual void log_info(const char *component, const char *format,...)
Log informational message.
Mutex mutual exclusion lock.
Read/write lock to allow multiple readers but only a single writer on the resource at a time.
Thread class encapsulation of pthreads.
const char * name() const
Get name of thread.
void set_name(const char *format,...)
Set name of thread.
void wakeup()
Wake up thread.
A class for handling time.
Wait until a given condition holds.
void wait()
Wait for the condition forever.
void wake_all()
Wake up all waiting threads.
Fawkes library namespace.
float deg2rad(float deg)
Convert an angle given in degrees to radians.
std::string str_join(const InputIterator &first, const InputIterator &last, char delim='/')
Join list of strings string using given delimiter.