yarp-devices
Loading...
Searching...
No Matches
PdoProtocol.hpp
1// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2
3#ifndef __PDO_PROTOCOL_HPP__
4#define __PDO_PROTOCOL_HPP__
5
6#include <cstddef>
7#include <cstdint>
8
9#include <functional>
10#include <type_traits>
11#include <utility> // std::forward
12
13#include "ICanSenderDelegate.hpp"
14#include "SdoClient.hpp"
15
16namespace roboticslab
17{
18
26{
27public:
38
40 constexpr PdoTransmissionType() = default;
41
43 constexpr PdoTransmissionType(transmission_type type) : type(type)
44 { }
45
47 constexpr operator std::uint8_t() const
48 { return type; }
49
51 static constexpr PdoTransmissionType SYNCHRONOUS_CYCLIC_N(std::uint8_t n)
52 { return static_cast<transmission_type>(n); }
53
55 template<std::uint8_t n>
57 {
58 // https://stackoverflow.com/a/12109644
59 static_assert(n >= 0x01 && n <= 0xF0, "Illegal argument."); // same as [1-240]
60 return static_cast<transmission_type>(n);
61 }
62
63private:
65};
66
67class PdoProtocol;
68
80{
81 friend PdoProtocol;
82
83public:
86
89
92
95
97 PdoConfiguration & setValid(bool value);
98
100 PdoConfiguration & setRtr(bool value);
101
104
106 PdoConfiguration & setInhibitTime(std::uint16_t value);
107
109 PdoConfiguration & setEventTimer(std::uint16_t value);
110
112 PdoConfiguration & setSyncStartValue(std::uint8_t value);
113
115 template<typename T>
116 PdoConfiguration & addMapping(std::uint16_t index, std::uint8_t subindex = 0x00)
117 {
118 static_assert(std::is_integral_v<T>, "Integral required.");
119 static_assert(sizeof(T) <= sizeof(std::uint32_t), "Size exceeds 4 bytes.");
120 addMappingInternal((index << 16) + (subindex << 8) + sizeof(T) * 8);
121 return *this;
122 }
123
124private:
125 void addMappingInternal(std::uint32_t value);
126
127 class Private;
128 Private * priv;
129};
130
138{
139public:
141 PdoProtocol(std::uint8_t id, std::uint16_t cob, unsigned int n, SdoClient * sdo)
142 : id(id), cob(cob), n(n), sdo(sdo)
143 { }
144
146 virtual ~PdoProtocol() = default;
147
149 std::uint16_t getCobId() const
150 { return cob + id; };
151
153 bool configure(const PdoConfiguration & config);
154
155protected:
157 enum class PdoType { RPDO, TPDO };
158
160 virtual PdoType getType() const = 0;
161
162 template<typename... Tn>
163 static constexpr std::size_t size()
164 { return (sizeof(Tn) + ... + 0); }
165
166 std::uint8_t id;
167 std::uint16_t cob;
168 unsigned int n;
169
170 SdoClient * sdo;
171};
172
177class ReceivePdo final : public PdoProtocol
178{
179public:
181 ReceivePdo(std::uint8_t id, std::uint16_t cob, unsigned int n, SdoClient * sdo, ICanSenderDelegate * sender = nullptr)
182 : PdoProtocol(id, cob, n, sdo), sender(sender)
183 { }
184
187 { this->sender = sender; }
188
196 template<typename... Ts>
197 bool write(Ts... data)
198 {
199 static_assert(sizeof...(Ts) > 0 && size<Ts...>() <= 8, "Illegal cumulative size.");
200 std::uint8_t raw[size<Ts...>()]; unsigned int count = 0;
201 (pack(&data, raw, &count), ...);
202 return writeInternal(raw, count);
203 }
204
205protected:
206 PdoType getType() const override
207 { return PdoType::RPDO; }
208
209private:
210 template<typename T>
211 void pack(const T * data, std::uint8_t * buff, unsigned int * count)
212 {
213 static_assert(std::is_integral_v<T>, "Integral required.");
214 packInternal(buff + *count, data, sizeof(T));
215 *count += sizeof(T);
216 }
217
218 void packInternal(std::uint8_t * buff, const void * data, unsigned int size);
219 bool writeInternal(const std::uint8_t * data, unsigned int size);
220
221 ICanSenderDelegate * sender;
222};
223
228class TransmitPdo final : public PdoProtocol
229{
230public:
231 using PdoProtocol::PdoProtocol; // inherit parent constructor
232
234 bool accept(const std::uint8_t * data, unsigned int size)
235 { return (bool)callback && callback(data, size); }
236
244 template<typename... Ts, typename Fn>
245 void registerHandler(Fn && fn)
246 {
247 static_assert(sizeof...(Ts) > 0 && size<Ts...>() <= 8, "Illegal cumulative size.");
248 callback = [this, fn](const std::uint8_t * raw, unsigned int len)
249 { unsigned int count = 0;
250 return size<Ts...>() == len && (ordered_call{fn, unpack<Ts>(raw, &count)...}, true); };
251 }
252
255 { callback = HandlerFn(); }
256
257protected:
258 PdoType getType() const override
259 { return PdoType::TPDO; }
260
261private:
262 using HandlerFn = std::function<bool(const std::uint8_t * data, unsigned int size)>;
263
264 // https://stackoverflow.com/a/14058638
266 {
267 template<typename Fn, typename... Ts>
268 ordered_call(Fn && fn, Ts &&... ts)
269 { std::forward<Fn>(fn)(std::forward<Ts>(ts)...); }
270 };
271
272 template<typename T>
273 T unpack(const std::uint8_t * buff, unsigned int * count)
274 {
275 static_assert(std::is_integral_v<T>, "Integral required.");
276 T data;
277 unpackInternal(&data, buff + *count, sizeof(T));
278 *count += sizeof(T);
279 return data;
280 }
281
282 void unpackInternal(void * data, const std::uint8_t * buff, unsigned int size);
283
284 HandlerFn callback;
285};
286
287} // namespace roboticslab
288
289#endif // __PDO_PROTOCOL_HPP__
Implementation-agnostic consumer for TX CAN transfers.
Definition ICanSenderDelegate.hpp:22
Set of SDO configuration values for a PdoProtocol.
Definition PdoProtocol.hpp:80
PdoConfiguration & setRtr(bool value)
Set or reset RTR bit.
Definition PdoProtocol.cpp:62
~PdoConfiguration()
Destructor.
Definition PdoProtocol.cpp:36
PdoConfiguration & setValid(bool value)
Set or reset valid bit.
Definition PdoProtocol.cpp:56
PdoConfiguration & setEventTimer(std::uint16_t value)
Set event timer.
Definition PdoProtocol.cpp:80
PdoConfiguration & setInhibitTime(std::uint16_t value)
Set inhibit time.
Definition PdoProtocol.cpp:74
PdoConfiguration & operator=(const PdoConfiguration &)
Copy assignment operator.
Definition PdoProtocol.cpp:45
PdoConfiguration & addMapping(std::uint16_t index, std::uint8_t subindex=0x00)
Configure PDO mapping, uses template parameter to deduce object size.
Definition PdoProtocol.hpp:116
PdoConfiguration()
Constructor.
Definition PdoProtocol.cpp:32
PdoConfiguration & setSyncStartValue(std::uint8_t value)
Set sync start value.
Definition PdoProtocol.cpp:86
PdoConfiguration & setTransmissionType(PdoTransmissionType value)
Set transmission type.
Definition PdoProtocol.cpp:68
Abstract representation of PDO protocol.
Definition PdoProtocol.hpp:138
bool configure(const PdoConfiguration &config)
Configure this PDO drive-side via SDO packages.
Definition PdoProtocol.cpp:97
virtual ~PdoProtocol()=default
Virtual destructor.
PdoType
PDO type.
Definition PdoProtocol.hpp:157
std::uint16_t getCobId() const
Retrieve COB ID.
Definition PdoProtocol.hpp:149
PdoProtocol(std::uint8_t id, std::uint16_t cob, unsigned int n, SdoClient *sdo)
Constructor, registers SDO client handle.
Definition PdoProtocol.hpp:141
virtual PdoType getType() const =0
Retrieve PDO type.
Wrapped enumeration of a PDO transmission type.
Definition PdoProtocol.hpp:26
transmission_type
Wrapped enumerators.
Definition PdoProtocol.hpp:30
@ EVENT_DRIVEN_DEVICE_APP_PROFILE
Device application profile-specific event-driven.
Definition PdoProtocol.hpp:36
@ SYNCHRONOUS_ACYCLIC
Synchronous acyclic.
Definition PdoProtocol.hpp:31
@ RTR_EVENT_DRIVEN
Event-driven RTR.
Definition PdoProtocol.hpp:34
@ RTR_SYNCHRONOUS
Synchronous RTR.
Definition PdoProtocol.hpp:33
@ EVENT_DRIVEN_MANUFACTURER
Manufacturer-specific event-driven.
Definition PdoProtocol.hpp:35
@ SYNCHRONOUS_CYCLIC
Synchronous cyclic.
Definition PdoProtocol.hpp:32
constexpr PdoTransmissionType()=default
Default constructor.
static constexpr PdoTransmissionType SYNCHRONOUS_CYCLIC_N(std::uint8_t n)
Cast input byte to an PdoTransmissionType enumerator.
Definition PdoProtocol.hpp:51
constexpr PdoTransmissionType(transmission_type type)
Constructor, accepts initial transmission type.
Definition PdoProtocol.hpp:43
static constexpr PdoTransmissionType SYNCHRONOUS_CYCLIC_N()
Cast input byte to an PdoTransmissionType enumerator, performs static check on range [0x01-0xF0].
Definition PdoProtocol.hpp:56
Representation of RPDO protocol.
Definition PdoProtocol.hpp:178
void configureSender(ICanSenderDelegate *sender)
Configure CAN sender delegate handle.
Definition PdoProtocol.hpp:186
PdoType getType() const override
Retrieve PDO type.
Definition PdoProtocol.hpp:206
ReceivePdo(std::uint8_t id, std::uint16_t cob, unsigned int n, SdoClient *sdo, ICanSenderDelegate *sender=nullptr)
Constructor, registers SDO and CAN sender handles.
Definition PdoProtocol.hpp:181
bool write(Ts... data)
Send data to the drive.
Definition PdoProtocol.hpp:197
Representation of SDO client protocol.
Definition SdoClient.hpp:32
Representation of TPDO protocol.
Definition PdoProtocol.hpp:229
void registerHandler(Fn &&fn)
Register callback.
Definition PdoProtocol.hpp:245
void unregisterHandler()
Unregister callback.
Definition PdoProtocol.hpp:254
PdoType getType() const override
Retrieve PDO type.
Definition PdoProtocol.hpp:258
bool accept(const std::uint8_t *data, unsigned int size)
Invoke registered callback on raw CAN message data.
Definition PdoProtocol.hpp:234
The main, catch-all namespace for Robotics Lab UC3M.
Definition groups.dox:6
Definition PdoProtocol.hpp:266