DeviceInterface.h
Go to the documentation of this file.
1 #pragma once
2 
3 
4 // STD/STL
5 #include <memory>
6 #include <string>
7 
8 // Simox
9 #include <VirtualRobot/Robot.h>
10 
11 // armarx
14 
16 
18 
19 #include "ErrorReporting.h"
20 
21 
23 {
24 
25  class SlaveInterface;
26 
27 
28  /**
29  * @class DeviceInterface
30  * @ingroup Library-ethercat
31  * @brief Brief description of class DeviceInterface.
32  *
33  * Detailed description of class DeviceInterface.
34  */
35  class DeviceInterface : public virtual DeviceBase
36  {
37 
38  public:
39  class SubDeviceInterface : public virtual DeviceBase
40  {
41  public:
42  SubDeviceInterface(const std::string& name) : DeviceBase{name}
43  {
44  }
45 
47  {
48  }
49  };
50 
51 
52  DeviceInterface(const std::string& name);
53 
54  virtual ~DeviceInterface()
55  {
56  }
57 
58  /**
59  * @brief Hook for executing code after the bus has successfully switched
60  * into the SafeOp-State.
61  * SDO of the slaves can be read and written.
62  * PDO data from the slaves have been read after switching to SafeOp,
63  * but no new updates to the slaves can bus until the bus in Op-state
64  */
65  virtual void
67  {
68  }
69 
70  /**
71  * @brief Hook for executing code after the bus has successfully switched
72  * into the Op-State.
73  * Before executing this hook, the PDO of all slaves have been updated at least once.
74  * Updates can be sent to slaves via PDO.
75  */
76  virtual void
78  {
79  }
80 
81  virtual void
83  {
84  }
85 
86  enum class TryAssignResult
87  {
88  /// Used if the slave was adpoted by this device. (Expected)
89  assigned,
90  /// Used if the slave is unknown to this device. (Expected)
91  unknown,
92  /// Used if the slave was already adopted before. (Error)
94  };
95 
96  /**
97  * @brief Method called by the EtherCAT bus to try to assign slaves
98  * to functional devices.
99  *
100  * @see TryAssignResult
101  * @param slave
102  *
103  * @return TryAssignResult holding the outcome of the method.
104  */
105  virtual TryAssignResult tryAssign(SlaveInterface& slave) = 0;
106 
107  enum class AllAssignedResult
108  {
109  /// Used if assignments were successful. (Expected)
110  ok,
111  /// Used if slaves are missing. (Error)
113  };
114 
115  /**
116  * @brief Method called by the EtherCAT bus after all slaves have
117  * been assigned.
118  *
119  * This method allows further initialization of assigned slaves and
120  * allows indicating missing slaves. When this method was called,
121  * all slaves have already been assigned, so if this device is still missing slaves,
122  * it should indicate it by returning `AllAssignedResult::slavesMissing`.
123  * `AllAssignedResult::ok` indicates that all expected slaves were assigned.
124  *
125  * @return `ok` if all expected slaves were assigned, `slavesMissing` otherwise.
126  */
127  virtual AllAssignedResult onAllAssigned() = 0;
128 
129  virtual std::string getClassName() const = 0;
130 
131  virtual const std::vector<std::shared_ptr<SubDeviceInterface>> getSubDevices() const;
132 
133  protected:
134  std::vector<std::shared_ptr<SubDeviceInterface>> subDevices;
135  };
136 
137 
138  template <typename Device>
139  std::shared_ptr<DeviceInterface>
141  {
142  return std::make_shared<Device>(config, robot);
143  }
144 
145 
146  template <typename SlaveI, typename Slave>
148  tryAssignUsingSerialNo(SlaveI& slave, Slave*& concreteSlave, std::uint32_t serialNo)
149  {
151 
152  using Result = DeviceInterface::TryAssignResult;
153 
154 
155  if (Slave::isSlaveIdentifierAccepted(slave.getSlaveIdentifier()))
156  {
157  Slave* upcastedSlave = dynamic_cast<Slave*>(&slave);
158 
159  if (upcastedSlave and upcastedSlave->getSlaveIdentifier().serialNumber == serialNo)
160  {
161  // Ensures that concreteSlave was not already assigned. Dynamic cast prevents errors with
162  // uninitialized pointers which are not nullptr.
163  if (concreteSlave == nullptr or dynamic_cast<SlaveI*>(concreteSlave) == nullptr)
164  {
165  concreteSlave = upcastedSlave;
166  return Result::assigned;
167  }
168 
169  return Result::alreadyAssigned;
170  }
171  }
172 
173  // Unknown slave.
174  return Result::unknown;
175  }
176 
177 } // namespace armarx::control::ethercat
armarx::control::ethercat::DeviceInterface::~DeviceInterface
virtual ~DeviceInterface()
Definition: DeviceInterface.h:54
armarx::control::ethercat::SlaveInterface
Brief description of class SlaveInterface.
Definition: SlaveInterface.h:29
armarx::control::ethercat::DeviceInterface::postSwitchToOp
virtual void postSwitchToOp()
Hook for executing code after the bus has successfully switched into the Op-State.
Definition: DeviceInterface.h:77
armarx::control::ethercat::DeviceInterface::tryAssign
virtual TryAssignResult tryAssign(SlaveInterface &slave)=0
Method called by the EtherCAT bus to try to assign slaves to functional devices.
armarx::control::ethercat::DeviceInterface::getClassName
virtual std::string getClassName() const =0
armarx::control::ethercat::DeviceInterface::SubDeviceInterface::~SubDeviceInterface
virtual ~SubDeviceInterface()
Definition: DeviceInterface.h:46
armarx::control::ethercat::DeviceInterface::SubDeviceInterface
Definition: DeviceInterface.h:39
armarx::control::ethercat::DeviceInterface::postSwitchToSafeOp
virtual void postSwitchToSafeOp()
Hook for executing code after the bus has successfully switched into the SafeOp-State.
Definition: DeviceInterface.h:66
armarx::control::ethercat::DeviceInterface::TryAssignResult::unknown
@ unknown
Used if the slave is unknown to this device. (Expected)
armarx::DeviceBase
Definition: DeviceBase.h:29
armarx::control::ethercat::tryAssignUsingSerialNo
DeviceInterface::TryAssignResult tryAssignUsingSerialNo(SlaveI &slave, Slave *&concreteSlave, std::uint32_t serialNo)
Definition: DeviceInterface.h:148
armarx::control::ethercat::DeviceInterface
Brief description of class DeviceInterface.
Definition: DeviceInterface.h:35
armarx::control::ethercat::DeviceInterface::TryAssignResult::assigned
@ assigned
Used if the slave was adpoted by this device. (Expected)
armarx::control::ethercat::DeviceInterface::AllAssignedResult::slavesMissing
@ slavesMissing
Used if slaves are missing. (Error)
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::control::hardware_config::DeviceConfig
Definition: DeviceConfig.h:42
DefaultRapidXmlReader.h
armarx::control::ethercat
Definition: Bus.cpp:24
armarx::control::ethercat::DeviceInterface::DeviceInterface
DeviceInterface(const std::string &name)
Definition: DeviceInterface.cpp:32
armarx::control::ethercat::DeviceInterface::TryAssignResult::alreadyAssigned
@ alreadyAssigned
Used if the slave was already adopted before. (Error)
armarx::control::ethercat::DeviceInterface::SubDeviceInterface::SubDeviceInterface
SubDeviceInterface(const std::string &name)
Definition: DeviceInterface.h:42
DeviceBase.h
DeviceConfig.h
ErrorReporting.h
armarx::control::ethercat::DeviceInterface::AllAssignedResult::ok
@ ok
Used if assignments were successful. (Expected)
armarx::control::ethercat::DeviceInterface::getSubDevices
virtual const std::vector< std::shared_ptr< SubDeviceInterface > > getSubDevices() const
Definition: DeviceInterface.cpp:37
armarx::control::ethercat::DeviceInterface::AllAssignedResult
AllAssignedResult
Definition: DeviceInterface.h:107
armarx::control::ethercat::DeviceInterface::execute
virtual void execute()
Definition: DeviceInterface.h:82
armarx::control::ethercat::DeviceInterface::subDevices
std::vector< std::shared_ptr< SubDeviceInterface > > subDevices
Definition: DeviceInterface.h:134
RapidXmlReader.h
armarx::control::ethercat::DeviceInterface::onAllAssigned
virtual AllAssignedResult onAllAssigned()=0
Method called by the EtherCAT bus after all slaves have been assigned.
armarx::control::ethercat::DeviceInterface::TryAssignResult
TryAssignResult
Definition: DeviceInterface.h:86
armarx::control::ethercat::createDevice
std::shared_ptr< DeviceInterface > createDevice(hardware_config::DeviceConfig &config, const VirtualRobot::RobotPtr &robot)
Definition: DeviceInterface.h:140
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18