SlaveRegisterReadingScheduler.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <atomic>
4 #include <condition_variable>
5 #include <mutex>
6 #include <thread>
7 
8 #include "EtherCATFrame.h"
9 #include "SlaveRegisters.h"
10 
12 {
13  /**
14  * @class SlaveRegisterReadingScheduler
15  * @ingroup Library-ethercat
16  * @brief Brief description of class SlaveRegisterReadingScheduler.
17  *
18  * Detailed description of class SlaveRegisterReadingScheduler.
19  */
21  {
22  public:
24  const std::vector<RegisterDataList>* requestedRegisters);
25 
26  static void
28  std::vector<RegisterDataList>* requestedRegisters);
29 
30 
31  SlaveRegisterReadingScheduler(std::uint16_t slaveCount,
32  unsigned int updatePeriodInMS,
33  std::vector<datatypes::RegisterEnum> registerList);
35 
36  const std::vector<RegisterDataList>& getRegisterData();
37 
39  bool allRegistersUpdated() const;
40 
41  private:
42  std::vector<RegisterDataList> registerData;
43 
44  EtherCATFrameList* frameList;
45 
46  void updateLoop();
47  unsigned int updatePeriodInMS{1};
48  std::thread errorRegisterUpdateThread;
49  std::atomic_bool errorRegisterUpdateThreadRunning{true};
50 
51  std::condition_variable cv_readNextRegisters;
52  std::mutex mutex_readNextRegisters;
53  std::atomic_bool readyToReadNextRegisters{true};
54  std::atomic_bool areAllRegistersUpdated{false};
55 
56  private:
57  /*!
58  * \brief Turn a map of which registers to read into a vector of addresses that must be read.
59  *
60  * Multi-byte registers are accounted for - every byte is added to the list individually.
61  * The returned list is sorted.
62  * \param toRead the register read map to turn into a list of addresses
63  * \return the sorted list of addresses
64  */
65  static std::vector<int> registerReadMapToAddressList(const RegisterDataList& toRead);
66 
67  /*!
68  * \brief Calculate the optimal separation of registers into intervals for PDUs.
69  *
70  * Note that the intervals may not be optimal once you pack them into EtherCAT frames
71  * because their size might lead to suboptimal fittings. Usually, the intervals
72  * shouldn't be that large though (an Ethernet frame fits 1500 bytes of payload, after all).
73  *
74  * The interval ends are exclusive (i.e., the interval is [start, end)).
75  * \param toRead the registers to fit into intervals
76  * \return a list of intervals that cover the registers optimally
77  */
78  static std::vector<std::pair<int, int>>
79  createFrameIntervals(const RegisterDataList& toRead);
80 
81  /*!
82  * \brief Create the PDUMetaData for a PDU in an EtherCAT frame.
83  * \param pduInterval the PDU interval (associated with a slave) to generate metadata for
84  * \param pduOffset the offset of the PDU relative to the start of the EtherCATFrame
85  * \return the PDU metadata
86  */
87  static PDUMetaData createPDUMetaData(std::tuple<uint16_t, int, int> pduInterval,
88  size_t pduOffset);
89 
90  /*!
91  * \brief Create an EtherCATFrame that reads all the given address intervals via FPRD
92  * if sent on the EtherCAT bus.
93  * \param slaveAssignedPDUIntervals the PDU intervals to fit in an EtherCATFrame
94  * \return the EtherCATFrame along with its metadata
95  * \exception std::length_error iff the PDUs are too long to fit in an EtherCAT frame
96  */
97  static std::pair<EtherCATFrame, EtherCATFrameMetaData>
98  createEtherCATFrame(std::vector<std::tuple<uint16_t, int, int>> slaveAssignedPDUIntervals);
99 
100  /*!
101  * \brief Create an EtherCATFrameList from the given address intervals.
102  *
103  * The frames will be generated to contain every interval for every slave.
104  *
105  * This method will try to fit the PDUs into the frames in order,
106  * starting a new frame if the next PDU doesn't fit. That is not optimal.
107  * If it bugs you, write something smarter.
108  * \param pduIntervals The address intervals to fit into EtherCAT frames
109  */
110  static EtherCATFrameList* createEtherCATFrameList(
111  const std::vector<std::pair<std::uint16_t, std::vector<std::pair<int, int>>>>&
112  pduIntervals);
113  };
114 
115 } // namespace armarx::control::ethercat
armarx::control::ethercat::PDUMetaData
The PDUMetaData struct holds information about the structure of a PDU.
Definition: EtherCATFrame.h:93
EtherCATFrame.h
armarx::control::ethercat::SlaveRegisterReadingScheduler::updateRegisterDataFromEtherCATFrameList
static void updateRegisterDataFromEtherCATFrameList(const EtherCATFrameList *frameList, std::vector< RegisterDataList > *requestedRegisters)
Definition: SlaveRegisterReadingScheduler.cpp:38
armarx::control::ethercat::SlaveRegisterReadingScheduler::~SlaveRegisterReadingScheduler
~SlaveRegisterReadingScheduler()
Definition: SlaveRegisterReadingScheduler.cpp:179
SlaveRegisters.h
armarx::control::ethercat::SlaveRegisterReadingScheduler::getRegisterData
const std::vector< RegisterDataList > & getRegisterData()
Definition: SlaveRegisterReadingScheduler.cpp:186
armarx::control::ethercat::RegisterDataList
Brief description of struct RegisterDataList.
Definition: SlaveRegisters.h:316
armarx::control::ethercat::EtherCATFrameList
The EtherCATFrameList struct holds a list of EtherCAT frames that can be scheduled in round-robin-sty...
Definition: EtherCATFrame.h:124
armarx::control::ethercat
Definition: Bus.cpp:24
armarx::control::ethercat::SlaveRegisterReadingScheduler::createEtherCATFrameListFromRegisterDataList
static EtherCATFrameList * createEtherCATFrameListFromRegisterDataList(const std::vector< RegisterDataList > *requestedRegisters)
Definition: SlaveRegisterReadingScheduler.cpp:20
armarx::control::ethercat::SlaveRegisterReadingScheduler::allRegistersUpdated
bool allRegistersUpdated() const
Definition: SlaveRegisterReadingScheduler.cpp:201
armarx::control::ethercat::SlaveRegisterReadingScheduler::SlaveRegisterReadingScheduler
SlaveRegisterReadingScheduler(std::uint16_t slaveCount, unsigned int updatePeriodInMS, std::vector< datatypes::RegisterEnum > registerList)
Definition: SlaveRegisterReadingScheduler.cpp:157
armarx::control::ethercat::SlaveRegisterReadingScheduler::startReadingNextRegisters
void startReadingNextRegisters()
Definition: SlaveRegisterReadingScheduler.cpp:192
armarx::control::ethercat::SlaveRegisterReadingScheduler
Brief description of class SlaveRegisterReadingScheduler.
Definition: SlaveRegisterReadingScheduler.h:20