1 #ifndef NODE_CANOPEN_BASE_DRIVER_IMPL
2 #define NODE_CANOPEN_BASE_DRIVER_IMPL
8 template <
class NODETYPE>
14 template <
class NODETYPE>
24 polling_ = this->config_[
"polling"].as<
bool>();
28 RCLCPP_ERROR(this->node_->get_logger(),
"Could not polling from config, setting to true.");
35 period_ms_ = this->config_[
"period"].as<std::uint32_t>();
39 RCLCPP_ERROR(this->node_->get_logger(),
"Could not read period from config, setting to 10ms");
49 polling_ = this->config_[
"polling"].as<
bool>();
53 RCLCPP_ERROR(this->node_->get_logger(),
"Could not polling from config, setting to true.");
60 period_ms_ = this->config_[
"period"].as<std::uint32_t>();
64 RCLCPP_ERROR(this->node_->get_logger(),
"Could not read period from config, setting to 10ms");
70 template <
class NODETYPE>
73 nmt_state_publisher_thread_ =
75 emcy_queue_ = this->lely_driver_->get_emcy_queue();
76 rpdo_queue_ = this->lely_driver_->get_rpdo_queue();
79 RCLCPP_INFO(this->node_->get_logger(),
"Starting with polling mode.");
80 poll_timer_ = this->node_->create_wall_timer(
81 std::chrono::milliseconds(period_ms_),
86 RCLCPP_INFO(this->node_->get_logger(),
"Starting with event mode.");
87 this->lely_driver_->set_sync_function(
92 template <
class NODETYPE>
95 nmt_state_publisher_thread_.join();
96 poll_timer_->cancel();
97 this->lely_driver_->unset_sync_function();
100 template <
class NODETYPE>
105 template <
class NODETYPE>
110 template <
class NODETYPE>
113 RCLCPP_INFO(this->node_->get_logger(),
"eds file %s", this->eds_.c_str());
114 RCLCPP_INFO(this->node_->get_logger(),
"bin file %s", this->bin_.c_str());
115 std::shared_ptr<std::promise<std::shared_ptr<ros2_canopen::LelyDriverBridge>>> prom;
116 prom = std::make_shared<std::promise<std::shared_ptr<ros2_canopen::LelyDriverBridge>>>();
117 std::future<std::shared_ptr<ros2_canopen::LelyDriverBridge>> f = prom->get_future();
121 std::scoped_lock<std::mutex> lock(this->driver_mutex_);
122 this->lely_driver_ = std::make_shared<ros2_canopen::LelyDriverBridge>(
123 *(this->exec_), *(this->master_), this->node_id_, this->node_->get_name(), this->eds_,
125 this->driver_ = std::static_pointer_cast<lely::canopen::BasicDriver>(this->lely_driver_);
126 prom->set_value(lely_driver_);
129 auto future_status = f.wait_for(this->non_transmit_timeout_);
130 if (future_status != std::future_status::ready)
132 RCLCPP_ERROR(this->node_->get_logger(),
"Adding timed out.");
135 this->lely_driver_ = f.get();
136 this->driver_ = std::static_pointer_cast<lely::canopen::BasicDriver>(this->lely_driver_);
137 if (!this->lely_driver_->IsReady())
139 RCLCPP_WARN(this->node_->get_logger(),
"Wait for device to boot.");
142 this->lely_driver_->wait_for_boot();
144 catch (
const std::exception & e)
146 RCLCPP_ERROR(this->node_->get_logger(), e.what());
149 RCLCPP_INFO(this->node_->get_logger(),
"Driver booted and ready.");
152 template <
class NODETYPE>
155 std::shared_ptr<std::promise<void>> prom = std::make_shared<std::promise<void>>();
156 auto f = prom->get_future();
160 this->driver_.reset();
161 this->lely_driver_.reset();
165 auto future_status = f.wait_for(this->non_transmit_timeout_);
166 if (future_status != std::future_status::ready)
171 template <
class NODETYPE>
176 std::future<lely::canopen::NmtState> f;
178 std::scoped_lock<std::mutex> lock(this->driver_mutex_);
179 f = this->lely_driver_->async_request_nmt();
181 while (f.wait_for(this->non_transmit_timeout_) != std::future_status::ready)
183 if (!this->activated_.load())
return;
187 auto state = f.get();
190 nmt_state_cb_(state, this->lely_driver_->get_id());
194 catch (
const std::future_error & e)
200 template <
class NODETYPE>
205 template <
class NODETYPE>
210 template <
class NODETYPE>
215 template <
class NODETYPE>
218 RCLCPP_INFO(this->node_->get_logger(),
"Starting RPDO Listener");
219 auto q = lely_driver_->get_rpdo_queue();
223 while (!q->wait_and_pop_for(this->non_transmit_timeout_, rpdo))
225 if (!this->activated_.load())
return;
231 rpdo_cb_(rpdo, this->lely_driver_->get_id());
235 catch (
const std::exception & e)
237 RCLCPP_ERROR_STREAM(this->node_->get_logger(),
"RPDO Listener error: " << e.what());
242 template <
class NODETYPE>
245 for (
int i = 0; i < 10; i++)
247 auto opt = emcy_queue_->try_pop();
248 if (!opt.has_value())
256 emcy_cb_(opt.value(), this->lely_driver_->get_id());
258 on_emcy(opt.value());
260 catch (
const std::exception & e)
262 RCLCPP_ERROR_STREAM(this->node_->get_logger(),
"EMCY poll error: " << e.what());
266 for (
int i = 0; i < 10; i++)
268 auto opt = rpdo_queue_->try_pop();
269 if (!opt.has_value())
277 rpdo_cb_(opt.value(), this->lely_driver_->get_id());
279 on_rpdo(opt.value());
281 catch (
const std::exception & e)
283 RCLCPP_ERROR_STREAM(this->node_->get_logger(),
"RPDO Poll error: " << e.what());
289 template <
class NODETYPE>
292 RCLCPP_INFO(this->node_->get_logger(),
"Starting EMCY Listener");
293 auto q = lely_driver_->get_emcy_queue();
297 while (!q->wait_and_pop_for(this->non_transmit_timeout_, emcy))
299 if (!this->activated_.load())
return;
305 emcy_cb_(emcy, this->lely_driver_->get_id());
309 catch (
const std::exception & e)
311 RCLCPP_ERROR_STREAM(this->node_->get_logger(),
"EMCY Listener error: " << e.what());
Driver Exception.
Definition: driver_error.hpp:17
Definition: node_canopen_base_driver.hpp:19
void rdpo_listener()
Definition: node_canopen_base_driver_impl.hpp:216
virtual void add_to_master()
Add the driver to master.
Definition: node_canopen_base_driver_impl.hpp:111
void nmt_listener()
Definition: node_canopen_base_driver_impl.hpp:172
virtual void on_rpdo(COData data)
Definition: node_canopen_base_driver_impl.hpp:206
virtual void poll_timer_callback()
Definition: node_canopen_base_driver_impl.hpp:243
NodeCanopenBaseDriver(NODETYPE *node)
Definition: node_canopen_base_driver_impl.hpp:9
virtual void remove_from_master()
Remove the driver from master.
Definition: node_canopen_base_driver_impl.hpp:153
void emcy_listener()
Definition: node_canopen_base_driver_impl.hpp:290
virtual void on_nmt(canopen::NmtState nmt_state)
Definition: node_canopen_base_driver_impl.hpp:201
virtual void on_emcy(COEmcy emcy)
Definition: node_canopen_base_driver_impl.hpp:211
Node Canopen Driver.
Definition: node_canopen_driver.hpp:46
void shutdown()
Shutdown the driver.
Definition: node_canopen_driver.hpp:323
void deactivate()
Deactivate the driver.
Definition: node_canopen_driver.hpp:251
void cleanup()
Cleanup the driver.
Definition: node_canopen_driver.hpp:291
void activate()
Activate the driver.
Definition: node_canopen_driver.hpp:209
void init()
Initialise the driver.
Definition: node_canopen_driver.hpp:113
void configure()
Configure the driver.
Definition: node_canopen_driver.hpp:161
Definition: node_canopen_driver.hpp:32
Definition: configuration_manager.hpp:28
Definition: exchange.hpp:26
Definition: exchange.hpp:34