Lely core libraries  2.2.5
slave.hpp
Go to the documentation of this file.
1 
22 #ifndef LELY_COCPP_SLAVE_HPP_
23 #define LELY_COCPP_SLAVE_HPP_
24 
25 #include <lely/coapp/node.hpp>
26 
27 #include <memory>
28 #include <string>
29 #include <utility>
30 
31 #include <cstddef>
32 
33 namespace lely {
34 
35 namespace canopen {
36 
38 class BasicSlave : public Node {
39  public:
60  explicit BasicSlave(ev_exec_t* exec, io::TimerBase& timer,
61  io::CanChannelBase& chan, const ::std::string& dcf_txt,
62  const ::std::string& dcf_bin = "", uint8_t id = 0xff);
63 
66  const ::std::string& dcf_txt,
67  const ::std::string& dcf_bin = "", uint8_t id = 0xff)
68  : BasicSlave(nullptr, timer, chan, dcf_txt, dcf_bin, id) {}
69 
70  virtual ~BasicSlave();
71 
78  void OnLifeGuarding(::std::function<void(bool)> on_life_guarding);
79 
80  protected:
81  class Object;
82  class ConstObject;
83 
88  class SubObject {
89  friend class Object;
90 
91  public:
92  SubObject(const SubObject&) = default;
93  SubObject(SubObject&&) = default;
94 
95  SubObject& operator=(const SubObject&) = default;
96  SubObject& operator=(SubObject&&) = default;
97 
108  template <class T>
109  SubObject&
110  operator=(T&& value) {
111  Set(::std::forward<T>(value));
112  return *this;
113  }
114 
123  template <class T>
124  operator T() const {
125  return Get<T>();
126  }
127 
138  const ::std::type_info&
139  Type() const {
140  return slave_->Type(idx_, subidx_);
141  }
142 
154  const ::std::type_info&
155  Type(::std::error_code& ec) const noexcept {
156  return slave_->Type(idx_, subidx_, ec);
157  }
158 
170  template <class T>
171  T
172  Get() const {
173  return id_ ? slave_->TpdoGet<T>(id_, idx_, subidx_)
174  : slave_->Get<T>(idx_, subidx_);
175  }
176 
189  template <class T>
190  T
191  Get(::std::error_code& ec) const noexcept {
192  return id_ ? slave_->TpdoGet<T>(id_, idx_, subidx_, ec)
193  : slave_->Get<T>(idx_, subidx_, ec);
194  }
195 
207  template <class T>
208  void
209  Set(T&& value) {
210  if (id_)
211  slave_->TpdoSet(id_, idx_, subidx_, ::std::forward<T>(value));
212  else
213  slave_->Set(idx_, subidx_, ::std::forward<T>(value));
214  }
215 
229  template <class T>
230  void
231  Set(T&& value, ::std::error_code& ec) noexcept {
232  if (id_)
233  slave_->TpdoSet(id_, idx_, subidx_, ::std::forward<T>(value), ec);
234  else
235  slave_->Set(idx_, subidx_, ::std::forward<T>(value), ec);
236  }
237 
249  void
250  Set(const void* p, ::std::size_t n) {
251  if (!id_) slave_->Set(idx_, subidx_, p, n);
252  }
253 
264  void
265  Set(const void* p, ::std::size_t n, ::std::error_code& ec) noexcept {
266  if (!id_) slave_->Set(idx_, subidx_, p, n, ec);
267  }
268 
279  void
281  if (id_)
282  slave_->TpdoSetEvent(id_, idx_, subidx_);
283  else
284  slave_->SetEvent(idx_, subidx_);
285  }
286 
297  void
298  SetEvent(::std::error_code& ec) noexcept {
299  if (id_)
300  slave_->TpdoSetEvent(id_, idx_, subidx_, ec);
301  else
302  slave_->SetEvent(idx_, subidx_, ec);
303  }
304 
305  private:
306  SubObject(BasicSlave* slave, uint8_t id, uint16_t idx,
307  uint8_t subidx) noexcept
308  : slave_(slave), idx_(idx), subidx_(subidx), id_(id) {}
309 
310  BasicSlave* slave_;
311  uint16_t idx_;
312  uint8_t subidx_;
313  uint8_t id_;
314  };
315 
321  friend class Object;
322  friend class ConstObject;
323 
324  public:
333  template <class T>
334  operator T() const {
335  return Get<T>();
336  }
337 
348  const ::std::type_info&
349  Type() const {
350  return slave_->Type(idx_, subidx_);
351  }
352 
365  const ::std::type_info&
366  Type(::std::error_code& ec) const {
367  return slave_->Type(idx_, subidx_, ec);
368  }
369 
382  template <class T>
383  T
384  Get() const {
385  return id_ ? (is_rpdo_ ? slave_->RpdoGet<T>(id_, idx_, subidx_)
386  : slave_->TpdoGet<T>(id_, idx_, subidx_))
387  : slave_->Get<T>(idx_, subidx_);
388  }
389 
403  template <class T>
404  T
405  Get(::std::error_code& ec) const noexcept {
406  return id_ ? (is_rpdo_ ? slave_->RpdoGet<T>(id_, idx_, subidx_, ec)
407  : slave_->TpdoGet<T>(id_, idx_, subidx_, ec))
408  : slave_->Get<T>(idx_, subidx_, ec);
409  }
410 
411  private:
412  ConstSubObject(const BasicSlave* slave, uint8_t id, uint16_t idx,
413  uint8_t subidx, bool is_rpdo) noexcept
414  : slave_(slave),
415  idx_(idx),
416  subidx_(subidx),
417  id_(id),
418  is_rpdo_(is_rpdo) {}
419 
420  const BasicSlave* slave_;
421  uint16_t idx_;
422  uint8_t subidx_;
423  uint8_t id_ : 7;
424  uint8_t is_rpdo_ : 1;
425  };
426 
427  class RpdoMapped;
428  class TpdoMapped;
429 
434  class Object {
435  class Mapped;
436  friend class BasicSlave;
437 
438  public:
450  SubObject operator[](uint8_t subidx) noexcept {
451  return SubObject(slave_, id_, idx_, subidx);
452  }
453 
465  ConstSubObject operator[](uint8_t subidx) const noexcept {
466  return ConstSubObject(slave_, id_, idx_, subidx, false);
467  }
468 
469  private:
470  Object(BasicSlave* slave, uint16_t idx) noexcept : Object(slave, 0, idx) {}
471 
472  Object(BasicSlave* slave, uint8_t id, uint16_t idx) noexcept
473  : slave_(slave), idx_(idx), id_(id) {}
474 
475  BasicSlave* slave_;
476  uint16_t idx_;
477  uint8_t id_;
478  };
479 
484  class ConstObject {
485  class RpdoMapped;
486  class TpdoMapped;
487  friend class BasicSlave;
488 
489  public:
501  ConstSubObject operator[](uint8_t subidx) const noexcept {
502  return ConstSubObject(slave_, id_, idx_, subidx, is_rpdo_);
503  }
504 
505  private:
506  ConstObject(const BasicSlave* slave, uint16_t idx) noexcept
507  : ConstObject(slave, 0, idx, false) {}
508 
509  ConstObject(const BasicSlave* slave, uint8_t id, uint16_t idx,
510  bool is_rpdo) noexcept
511  : slave_(slave), idx_(idx), id_(id), is_rpdo_(is_rpdo) {}
512 
513  const BasicSlave* slave_;
514  uint16_t idx_;
515  uint8_t id_ : 7;
516  uint8_t is_rpdo_ : 1;
517  };
518 
523  class RpdoMapped {
524  friend class BasicSlave;
525 
526  public:
537  ConstObject operator[](uint16_t idx) const noexcept {
538  return ConstObject(slave_, id_, idx, true);
539  }
540 
541  private:
542  RpdoMapped(const BasicSlave* slave, uint8_t id) noexcept
543  : slave_(slave), id_(id) {}
544 
545  const BasicSlave* slave_;
546  uint8_t id_;
547  };
548 
553  class TpdoMapped {
554  friend class BasicSlave;
555 
556  public:
567  Object operator[](uint16_t idx) noexcept {
568  return Object(slave_, id_, idx);
569  }
570 
581  ConstObject operator[](uint16_t idx) const noexcept {
582  return ConstObject(slave_, id_, idx, false);
583  }
584 
585  private:
586  TpdoMapped(BasicSlave* slave, uint8_t id) noexcept
587  : slave_(slave), id_(id) {}
588 
589  BasicSlave* slave_;
590  uint8_t id_;
591  };
592 
608  template <class T>
609  using OnReadSignature = ::std::error_code(uint16_t idx, uint8_t subdx,
610  T& value);
611 
629  template <class T>
630  using OnWriteSignature = typename ::std::conditional<
632  ::std::error_code(uint16_t idx, uint8_t subidx, T& new_val, T old_val),
633  ::std::error_code(uint16_t idx, uint8_t subidx, T& new_val)>::type;
634 
645  Object operator[](::std::ptrdiff_t idx) noexcept { return Object(this, idx); }
646 
657  ConstObject operator[](::std::ptrdiff_t idx) const noexcept {
658  return ConstObject(this, idx);
659  }
660 
671  RpdoMapped
672  RpdoMapped(uint8_t id) const noexcept {
673  return {this, id};
674  }
675 
686  TpdoMapped
687  TpdoMapped(uint8_t id) noexcept {
688  return {this, id};
689  }
690 
703  template <class T>
704  typename ::std::enable_if<detail::is_canopen_type<T>::value>::type OnRead(
705  uint16_t idx, uint8_t subidx, ::std::function<OnReadSignature<T>> ind);
706 
718  template <class T>
719  typename ::std::enable_if<detail::is_canopen_type<T>::value>::type OnRead(
720  uint16_t idx, uint8_t subidx, ::std::function<OnReadSignature<T>> ind,
721  ::std::error_code& ec);
722 
735  template <class T>
736  typename ::std::enable_if<detail::is_canopen_type<T>::value>::type OnRead(
737  uint16_t idx, ::std::function<OnReadSignature<T>> ind);
738 
750  template <class T>
751  typename ::std::enable_if<detail::is_canopen_type<T>::value>::type OnRead(
752  uint16_t idx, ::std::function<OnReadSignature<T>> ind,
753  ::std::error_code& ec);
754 
768  template <class T>
769  typename ::std::enable_if<detail::is_canopen_type<T>::value>::type OnWrite(
770  uint16_t idx, uint8_t subidx, ::std::function<OnWriteSignature<T>> ind);
771 
784  template <class T>
785  typename ::std::enable_if<detail::is_canopen_type<T>::value>::type OnWrite(
786  uint16_t idx, uint8_t subidx, ::std::function<OnWriteSignature<T>> ind,
787  ::std::error_code& ec);
788 
801  template <class T>
802  typename ::std::enable_if<detail::is_canopen_type<T>::value>::type OnWrite(
803  uint16_t idx, ::std::function<OnWriteSignature<T>> ind);
804 
816  template <class T>
817  typename ::std::enable_if<detail::is_canopen_type<T>::value>::type OnWrite(
818  uint16_t idx, ::std::function<OnWriteSignature<T>> ind,
819  ::std::error_code& ec);
820 #ifndef DOXYGEN_SHOULD_SKIP_THIS
821 
822  private:
823 #endif
824 
833  virtual void
834  OnLifeGuarding(bool occurred) noexcept {
835  (void)occurred;
836  };
837 #ifdef DOXYGEN_SHOULD_SKIP_THIS
838 
839  private:
840 #endif
841  struct Impl_;
842  ::std::unique_ptr<Impl_> impl_;
843 };
844 
845 } // namespace canopen
846 
847 } // namespace lely
848 
849 #endif // LELY_COCPP_SLAVE_HPP_
lely::canopen::BasicSlave::SubObject::SetEvent
void SetEvent(::std::error_code &ec) noexcept
Checks if the sub-object can be mapped into a PDO and, if so, triggers the transmission of every acyc...
Definition: slave.hpp:298
lely::canopen::BasicSlave
The base class for CANopen slaves.
Definition: slave.hpp:38
lely::canopen::BasicSlave::SubObject::Set
void Set(T &&value, ::std::error_code &ec) noexcept
Writes a value to the sub-object.
Definition: slave.hpp:231
ev_exec_t
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
lely::canopen::BasicSlave::ConstSubObject
An accessor providing read-only access to a CANopen sub-object in a local object dictionary.
Definition: slave.hpp:320
lely::canopen::BasicSlave::Object::operator[]
SubObject operator[](uint8_t subidx) noexcept
Returns a mutator object that provides read/write access to the specified CANopen sub-object in the l...
Definition: slave.hpp:450
lely::canopen::Device::Set
typename ::std::enable_if< detail::is_canopen_basic< T >::value >::type Set(uint16_t idx, uint8_t subidx, T value)
Writes a CANopen basic value to a sub-object.
lely::io::TimerBase
A reference to an abstract timer.
Definition: timer.hpp:130
lely::canopen::BasicSlave::ConstSubObject::Get
T Get(::std::error_code &ec) const noexcept
Reads the value of the sub-object.
Definition: slave.hpp:405
lely::canopen::BasicSlave::SubObject::Set
void Set(const void *p, ::std::size_t n, ::std::error_code &ec) noexcept
Writes an OCTET_STRING or DOMAIN value to the sub-object.
Definition: slave.hpp:265
lely::canopen::BasicSlave::ConstSubObject::Type
const ::std::type_info & Type(::std::error_code &ec) const
Returns the type of the sub-object.
Definition: slave.hpp:366
lely::canopen::BasicSlave::OnLifeGuarding
void OnLifeGuarding(::std::function< void(bool)> on_life_guarding)
Registers the function to be invoked when a life guarding event occurs or is resolved.
Definition: slave.cpp:87
lely::canopen::BasicSlave::TpdoMapped::operator[]
Object operator[](uint16_t idx) noexcept
Returns a mutator object that provides read/write access to the specified TPDO-mapped object in the r...
Definition: slave.hpp:567
lely::canopen::Device::TpdoSetEvent
void TpdoSetEvent(uint8_t id, uint16_t idx, uint8_t subidx)
Triggers the transmission of every event-driven, asynchronous Transmit-PDO which is mapped into the s...
Definition: device.cpp:1384
lely::canopen::BasicSlave::ConstSubObject::Get
T Get() const
Reads the value of the sub-object.
Definition: slave.hpp:384
lely::canopen::BasicSlave::SubObject::Set
void Set(const void *p, ::std::size_t n)
Writes an OCTET_STRING or DOMAIN value to the sub-object.
Definition: slave.hpp:250
node.hpp
lely::canopen::BasicSlave::TpdoMapped::operator[]
ConstObject operator[](uint16_t idx) const noexcept
Returns an accessor object that provides read-only access to the specified TPDO-mapped object in the ...
Definition: slave.hpp:581
lely::canopen::BasicSlave::ConstSubObject::Type
const ::std::type_info & Type() const
Returns the type of the sub-object.
Definition: slave.hpp:349
lely::canopen::BasicSlave::SubObject::Type
const ::std::type_info & Type() const
Returns the type of the sub-object.
Definition: slave.hpp:139
lely::canopen::BasicSlave::OnRead
typename ::std::enable_if< detail::is_canopen_type< T >::value >::type OnRead(uint16_t idx, uint8_t subidx, ::std::function< OnReadSignature< T >> ind)
Registers a callback function to be invoked on read (SDO upload) access to the specified CANopen sub-...
lely::io::CanChannelBase
A reference to an abstract CAN channel.
Definition: can.hpp:429
lely::canopen::BasicSlave::operator[]
Object operator[](::std::ptrdiff_t idx) noexcept
Returns a mutator object that provides read/write access to the specified CANopen object in the local...
Definition: slave.hpp:645
lely::canopen::BasicSlave::Object
A mutator providing read/write access to a CANopen object in a local object dictionary.
Definition: slave.hpp:434
lely::canopen::detail::is_canopen_basic
If T is one of the CANopen basic types, provides the member constant value equal to true.
Definition: type_traits.hpp:42
lely::canopen::Device::TpdoSet
typename ::std::enable_if< detail::is_canopen_basic< T >::value >::type TpdoSet(uint8_t id, uint16_t idx, uint8_t subidx, T value)
Writes a value to a sub-object in a remote object dictionary by writing to the corresponding PDO-mapp...
lely::canopen::BasicSlave::SubObject::Get
T Get() const
Reads the value of the sub-object.
Definition: slave.hpp:172
lely::canopen::Device::TpdoGet
typename ::std::enable_if< detail::is_canopen_basic< T >::value, T >::type TpdoGet(uint8_t id, uint16_t idx, uint8_t subidx) const
Reads the value of a TPDO-mapped sub-object in the local object dictionary that will be written to an...
lely::canopen::Device::id
uint8_t id() const noexcept
Returns the node-ID.
Definition: device.cpp:161
lely::canopen::BasicSlave::TpdoMapped
A mutator providing read/write access to TPDO-mapped objects in a remote object dictionary.
Definition: slave.hpp:553
lely::canopen::Device::SetEvent
void SetEvent(uint16_t idx, uint8_t subidx)
Checks if the specified sub-object in the local object dictionary can be mapped into a PDO and,...
Definition: device.cpp:1163
lely::canopen::BasicSlave::OnWriteSignature
typename ::std::conditional< detail::is_canopen_basic< T >::value, ::std::error_code(uint16_t idx, uint8_t subidx, T &new_val, T old_val), ::std::error_code(uint16_t idx, uint8_t subidx, T &new_val)>::type OnWriteSignature
The signature of the callback function invoked on write (SDO download) access to the local object dic...
Definition: slave.hpp:633
lely::canopen::BasicSlave::SubObject
A mutator providing read/write access to a CANopen sub-object in a local object dictionary.
Definition: slave.hpp:88
lely::canopen::BasicSlave::SubObject::operator=
SubObject & operator=(T &&value)
Sets the value of the sub-object.
Definition: slave.hpp:110
lely::canopen::BasicSlave::RpdoMapped
An accessor providing read-only access to RPDO-mapped objects in a remote object dictionary.
Definition: slave.hpp:523
lely::canopen::BasicSlave::BasicSlave
BasicSlave(io::TimerBase &timer, io::CanChannelBase &chan, const ::std::string &dcf_txt, const ::std::string &dcf_bin="", uint8_t id=0xff)
Creates a new CANopen slave.
Definition: slave.hpp:65
lely::canopen::BasicSlave::RpdoMapped
RpdoMapped RpdoMapped(uint8_t id) const noexcept
Returns an accessor object that provides read-only access to RPDO-mapped objects in the remote object...
Definition: slave.hpp:672
lely::canopen::BasicSlave::SubObject::Type
const ::std::type_info & Type(::std::error_code &ec) const noexcept
Returns the type of the sub-object.
Definition: slave.hpp:155
lely::canopen::BasicSlave::ConstObject
An accessor providing read-only access to a CANopen object in a local object dictionary.
Definition: slave.hpp:484
lely::canopen::Device::Get
typename ::std::enable_if< detail::is_canopen_type< T >::value, T >::type Get(uint16_t idx, uint8_t subidx) const
Reads the value of a sub-object.
lely::canopen::BasicSlave::ConstObject::operator[]
ConstSubObject operator[](uint8_t subidx) const noexcept
Returns an accessor object that provides read-only access to the specified CANopen sub-object in the ...
Definition: slave.hpp:501
lely::canopen::BasicSlave::Object::operator[]
ConstSubObject operator[](uint8_t subidx) const noexcept
Returns an accessor object that provides read-only access to the specified CANopen sub-object in the ...
Definition: slave.hpp:465
lely::canopen::BasicSlave::OnReadSignature
::std::error_code(uint16_t idx, uint8_t subdx, T &value) OnReadSignature
The signature of the callback function invoked on read (SDO upload) access to the local object dictio...
Definition: slave.hpp:610
lely::canopen::BasicSlave::BasicSlave
BasicSlave(ev_exec_t *exec, io::TimerBase &timer, io::CanChannelBase &chan, const ::std::string &dcf_txt, const ::std::string &dcf_bin="", uint8_t id=0xff)
Creates a new CANopen slave.
Definition: slave.cpp:78
lely::canopen::Node
The base class for CANopen nodes.
Definition: node.hpp:115
lely::canopen::BasicSlave::OnLifeGuarding
virtual void OnLifeGuarding(bool occurred) noexcept
The function invoked when a life guarding event occurs or is resolved.
Definition: slave.hpp:834
lely::canopen::BasicSlave::OnWrite
typename ::std::enable_if< detail::is_canopen_type< T >::value >::type OnWrite(uint16_t idx, uint8_t subidx, ::std::function< OnWriteSignature< T >> ind)
Registers a callback function to be invoked on write (SDO download) access to the specified CANopen s...
lely::canopen::Device::Type
const ::std::type_info & Type(uint16_t idx, uint8_t subidx) const
Returns the type of a sub-object.
Definition: device.cpp:728
lely::canopen::Device::RpdoGet
typename ::std::enable_if< detail::is_canopen_basic< T >::value, T >::type RpdoGet(uint8_t id, uint16_t idx, uint8_t subidx) const
Reads the value of a sub-object in a remote object dictionary by reading the corresponding PDO-mapped...
lely::canopen::BasicSlave::operator[]
ConstObject operator[](::std::ptrdiff_t idx) const noexcept
Returns an accessor object that provides read-only access to the specified CANopen object in the loca...
Definition: slave.hpp:657
lely::canopen::BasicSlave::SubObject::Get
T Get(::std::error_code &ec) const noexcept
Reads the value of the sub-object.
Definition: slave.hpp:191
lely::canopen::BasicSlave::RpdoMapped::operator[]
ConstObject operator[](uint16_t idx) const noexcept
Returns an accessor object that provides read-only access to the specified RPDO-mapped object in the ...
Definition: slave.hpp:537
lely::canopen::BasicSlave::SubObject::SetEvent
void SetEvent()
Checks if the sub-object can be mapped into a PDO and, if so, triggers the transmission of every acyc...
Definition: slave.hpp:280
lely::canopen::BasicSlave::TpdoMapped
TpdoMapped TpdoMapped(uint8_t id) noexcept
Returns a mutator object that provides read/write access to TPDO-mapped objects in the remote object ...
Definition: slave.hpp:687
lely::canopen::BasicSlave::SubObject::Set
void Set(T &&value)
Writes a value to the sub-object.
Definition: slave.hpp:209