Lely core libraries  2.3.4
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  return Set(::std::forward<T>(value));
112  }
113 
122  template <class T>
123  operator T() const {
124  return Get<T>();
125  }
126 
137  const ::std::type_info&
138  Type() const {
139  return slave_->Type(idx_, subidx_);
140  }
141 
153  const ::std::type_info&
154  Type(::std::error_code& ec) const noexcept {
155  return slave_->Type(idx_, subidx_, ec);
156  }
157 
169  template <class T>
170  T
171  Get() const {
172  return id_ ? slave_->TpdoGet<T>(id_, idx_, subidx_)
173  : slave_->Get<T>(idx_, subidx_);
174  }
175 
188  template <class T>
189  T
190  Get(::std::error_code& ec) const noexcept {
191  return id_ ? slave_->TpdoGet<T>(id_, idx_, subidx_, ec)
192  : slave_->Get<T>(idx_, subidx_, ec);
193  }
194 
208  template <class T>
209  SubObject&
210  Set(T&& value) {
211  if (id_)
212  slave_->TpdoSet(id_, idx_, subidx_, ::std::forward<T>(value));
213  else
214  slave_->Set(idx_, subidx_, ::std::forward<T>(value));
215  return *this;
216  }
217 
233  template <class T>
234  SubObject&
235  Set(T&& value, ::std::error_code& ec) noexcept {
236  if (id_)
237  slave_->TpdoSet(id_, idx_, subidx_, ::std::forward<T>(value), ec);
238  else
239  slave_->Set(idx_, subidx_, ::std::forward<T>(value), ec);
240  return *this;
241  }
242 
256  SubObject&
257  Set(const void* p, ::std::size_t n) {
258  if (!id_) slave_->Set(idx_, subidx_, p, n);
259  return *this;
260  }
261 
274  SubObject&
275  Set(const void* p, ::std::size_t n, ::std::error_code& ec) noexcept {
276  if (!id_) slave_->Set(idx_, subidx_, p, n, ec);
277  return *this;
278  }
279 
290  void
292  if (id_)
293  slave_->TpdoSetEvent(id_, idx_, subidx_);
294  else
295  slave_->SetEvent(idx_, subidx_);
296  }
297 
308  void
309  SetEvent(::std::error_code& ec) noexcept {
310  if (id_)
311  slave_->TpdoSetEvent(id_, idx_, subidx_, ec);
312  else
313  slave_->SetEvent(idx_, subidx_, ec);
314  }
315 
316  private:
317  SubObject(BasicSlave* slave, uint8_t id, uint16_t idx,
318  uint8_t subidx) noexcept
319  : slave_(slave), idx_(idx), subidx_(subidx), id_(id) {}
320 
321  BasicSlave* slave_;
322  uint16_t idx_;
323  uint8_t subidx_;
324  uint8_t id_;
325  };
326 
332  friend class Object;
333  friend class ConstObject;
334 
335  public:
344  template <class T>
345  operator T() const {
346  return Get<T>();
347  }
348 
359  const ::std::type_info&
360  Type() const {
361  return slave_->Type(idx_, subidx_);
362  }
363 
376  const ::std::type_info&
377  Type(::std::error_code& ec) const {
378  return slave_->Type(idx_, subidx_, ec);
379  }
380 
393  template <class T>
394  T
395  Get() const {
396  return id_ ? (is_rpdo_ ? slave_->RpdoGet<T>(id_, idx_, subidx_)
397  : slave_->TpdoGet<T>(id_, idx_, subidx_))
398  : slave_->Get<T>(idx_, subidx_);
399  }
400 
414  template <class T>
415  T
416  Get(::std::error_code& ec) const noexcept {
417  return id_ ? (is_rpdo_ ? slave_->RpdoGet<T>(id_, idx_, subidx_, ec)
418  : slave_->TpdoGet<T>(id_, idx_, subidx_, ec))
419  : slave_->Get<T>(idx_, subidx_, ec);
420  }
421 
422  private:
423  ConstSubObject(const BasicSlave* slave, uint8_t id, uint16_t idx,
424  uint8_t subidx, bool is_rpdo) noexcept
425  : slave_(slave),
426  idx_(idx),
427  subidx_(subidx),
428  id_(id),
429  is_rpdo_(is_rpdo) {}
430 
431  const BasicSlave* slave_;
432  uint16_t idx_;
433  uint8_t subidx_;
434  uint8_t id_ : 7;
435  uint8_t is_rpdo_ : 1;
436  };
437 
438  class RpdoMapped;
439  class TpdoMapped;
440 
445  class Object {
446  class Mapped;
447  friend class BasicSlave;
448 
449  public:
461  SubObject
462  operator[](uint8_t subidx) noexcept {
463  return SubObject(slave_, id_, idx_, subidx);
464  }
465 
478  operator[](uint8_t subidx) const noexcept {
479  return ConstSubObject(slave_, id_, idx_, subidx, false);
480  }
481 
482  private:
483  Object(BasicSlave* slave, uint16_t idx) noexcept : Object(slave, 0, idx) {}
484 
485  Object(BasicSlave* slave, uint8_t id, uint16_t idx) noexcept
486  : slave_(slave), idx_(idx), id_(id) {}
487 
488  BasicSlave* slave_;
489  uint16_t idx_;
490  uint8_t id_;
491  };
492 
497  class ConstObject {
498  class RpdoMapped;
499  class TpdoMapped;
500  friend class BasicSlave;
501 
502  public:
515  operator[](uint8_t subidx) const noexcept {
516  return ConstSubObject(slave_, id_, idx_, subidx, is_rpdo_);
517  }
518 
519  private:
520  ConstObject(const BasicSlave* slave, uint16_t idx) noexcept
521  : ConstObject(slave, 0, idx, false) {}
522 
523  ConstObject(const BasicSlave* slave, uint8_t id, uint16_t idx,
524  bool is_rpdo) noexcept
525  : slave_(slave), idx_(idx), id_(id), is_rpdo_(is_rpdo) {}
526 
527  const BasicSlave* slave_;
528  uint16_t idx_;
529  uint8_t id_ : 7;
530  uint8_t is_rpdo_ : 1;
531  };
532 
537  class RpdoMapped {
538  friend class BasicSlave;
539 
540  public:
552  operator[](uint16_t idx) const noexcept {
553  return ConstObject(slave_, id_, idx, true);
554  }
555 
556  private:
557  RpdoMapped(const BasicSlave* slave, uint8_t id) noexcept
558  : slave_(slave), id_(id) {}
559 
560  const BasicSlave* slave_;
561  uint8_t id_;
562  };
563 
568  class TpdoMapped {
569  friend class BasicSlave;
570 
571  public:
582  Object
583  operator[](uint16_t idx) noexcept {
584  return Object(slave_, id_, idx);
585  }
586 
598  operator[](uint16_t idx) const noexcept {
599  return ConstObject(slave_, id_, idx, false);
600  }
601 
602  private:
603  TpdoMapped(BasicSlave* slave, uint8_t id) noexcept
604  : slave_(slave), id_(id) {}
605 
606  BasicSlave* slave_;
607  uint8_t id_;
608  };
609 
625  template <class T>
626  using OnReadSignature = ::std::error_code(uint16_t idx, uint8_t subdx,
627  T& value);
628 
646  template <class T>
647  using OnWriteSignature = typename ::std::conditional<
649  ::std::error_code(uint16_t idx, uint8_t subidx, T& new_val, T old_val),
650  ::std::error_code(uint16_t idx, uint8_t subidx, T& new_val)>::type;
651 
662  Object
663  operator[](::std::ptrdiff_t idx) noexcept {
664  return Object(this, idx);
665  }
666 
677  ConstObject
678  operator[](::std::ptrdiff_t idx) const noexcept {
679  return ConstObject(this, idx);
680  }
681 
692  RpdoMapped
693  RpdoMapped(uint8_t id) const noexcept {
694  return {this, id};
695  }
696 
707  TpdoMapped
708  TpdoMapped(uint8_t id) noexcept {
709  return {this, id};
710  }
711 
724  template <class T>
725  typename ::std::enable_if<is_canopen<T>::value>::type OnRead(
726  uint16_t idx, uint8_t subidx, ::std::function<OnReadSignature<T>> ind);
727 
739  template <class T>
740  typename ::std::enable_if<is_canopen<T>::value>::type OnRead(
741  uint16_t idx, uint8_t subidx, ::std::function<OnReadSignature<T>> ind,
742  ::std::error_code& ec);
743 
756  template <class T>
757  typename ::std::enable_if<is_canopen<T>::value>::type OnRead(
758  uint16_t idx, ::std::function<OnReadSignature<T>> ind);
759 
771  template <class T>
772  typename ::std::enable_if<is_canopen<T>::value>::type OnRead(
773  uint16_t idx, ::std::function<OnReadSignature<T>> ind,
774  ::std::error_code& ec);
775 
789  template <class T>
790  typename ::std::enable_if<is_canopen<T>::value>::type OnWrite(
791  uint16_t idx, uint8_t subidx, ::std::function<OnWriteSignature<T>> ind);
792 
805  template <class T>
806  typename ::std::enable_if<is_canopen<T>::value>::type OnWrite(
807  uint16_t idx, uint8_t subidx, ::std::function<OnWriteSignature<T>> ind,
808  ::std::error_code& ec);
809 
822  template <class T>
823  typename ::std::enable_if<is_canopen<T>::value>::type OnWrite(
824  uint16_t idx, ::std::function<OnWriteSignature<T>> ind);
825 
837  template <class T>
838  typename ::std::enable_if<is_canopen<T>::value>::type OnWrite(
839  uint16_t idx, ::std::function<OnWriteSignature<T>> ind,
840  ::std::error_code& ec);
841 
842  protected:
843  using Device::OnWrite;
844 
845  private:
855  virtual void
856  OnLifeGuarding(bool occurred) noexcept {
857  (void)occurred;
858  };
859 
860  struct Impl_;
861  ::std::unique_ptr<Impl_> impl_;
862 };
863 
864 } // namespace canopen
865 
866 } // namespace lely
867 
868 #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:309
lely::canopen::BasicSlave
The base class for CANopen slaves.
Definition: slave.hpp:38
ev_exec_t
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
lely::canopen::BasicSlave::SubObject::Set
SubObject & Set(const void *p, ::std::size_t n)
Writes an OCTET_STRING or DOMAIN value to the sub-object.
Definition: slave.hpp:257
lely::canopen::BasicSlave::ConstSubObject
An accessor providing read-only access to a CANopen sub-object in a local object dictionary.
Definition: slave.hpp:331
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:462
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:416
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:377
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:624
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:583
lely::canopen::Device::TpdoSet
typename ::std::enable_if< 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::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:1579
lely::canopen::BasicSlave::ConstSubObject::Get
T Get() const
Reads the value of the sub-object.
Definition: slave.hpp:395
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:598
lely::canopen::BasicSlave::ConstSubObject::Type
const ::std::type_info & Type() const
Returns the type of the sub-object.
Definition: slave.hpp:360
lely::canopen::Device::Get
typename ::std::enable_if< is_canopen< T >::value, T >::type Get(uint16_t idx, uint8_t subidx) const
Reads the value of a sub-object.
lely::canopen::BasicSlave::SubObject::Type
const ::std::type_info & Type() const
Returns the type of the sub-object.
Definition: slave.hpp:138
lely::io::CanChannelBase
A reference to an abstract CAN channel.
Definition: can.hpp:430
lely::canopen::BasicSlave::SubObject::Set
SubObject & 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:275
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:663
lely::canopen::BasicSlave::Object
A mutator providing read/write access to a CANopen object in a local object dictionary.
Definition: slave.hpp:445
lely::canopen::BasicSlave::SubObject::Get
T Get() const
Reads the value of the sub-object.
Definition: slave.hpp:171
lely::canopen::Device::id
uint8_t id() const noexcept
Returns the node-ID.
Definition: device.cpp:193
lely::canopen::is_canopen_basic
If T is one of the CANopen basic types, provides the member constant value equal to true.
Definition: type_traits.hpp:340
lely::canopen::BasicSlave::TpdoMapped
A mutator providing read/write access to TPDO-mapped objects in a remote object dictionary.
Definition: slave.hpp:568
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:1353
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:537
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:693
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:154
lely::canopen::BasicSlave::ConstObject
An accessor providing read-only access to a CANopen object in a local object dictionary.
Definition: slave.hpp:497
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:515
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:478
lely::canopen::BasicSlave::OnRead
typename ::std::enable_if< is_canopen< 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::canopen::BasicSlave::SubObject::Set
SubObject & Set(T &&value)
Writes a value to the sub-object.
Definition: slave.hpp:210
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:627
lely::canopen::BasicSlave::OnWrite
typename ::std::enable_if< is_canopen< 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::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:76
lely::canopen::Device::Set
typename ::std::enable_if< is_canopen< T >::value >::type Set(uint16_t idx, uint8_t subidx, const T &value)
Writes a CANopen value to a sub-object.
lely::canopen::Node
The base class for CANopen nodes.
Definition: node.hpp:116
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:856
lely::canopen::Device::RpdoGet
typename ::std::enable_if< 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::Device::TpdoGet
typename ::std::enable_if< 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::BasicSlave::SubObject::Set
SubObject & Set(T &&value, ::std::error_code &ec) noexcept
Writes a value to the sub-object.
Definition: slave.hpp:235
lely::canopen::BasicSlave::OnWriteSignature
typename ::std::conditional< 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:650
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:833
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:678
lely::canopen::BasicSlave::SubObject::Get
T Get(::std::error_code &ec) const noexcept
Reads the value of the sub-object.
Definition: slave.hpp:190
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:552
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:291
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:708