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