MotionLib  1.0.0
SamBuCa motion library
GrblPlatform.hpp
1 /*
2 ** Copyright (C) 2021 CERN
3 **
4 ** This software is provided 'as-is', without any express or implied
5 ** warranty. In no event will the authors be held liable for any damages
6 ** arising from the use of this software.
7 **
8 ** Permission is granted to anyone to use this software for any purpose,
9 ** including commercial applications, and to alter it and redistribute it
10 ** freely, subject to the following restrictions:
11 **
12 ** 1. The origin of this software must not be misrepresented; you must not
13 ** claim that you wrote the original software. If you use this software
14 ** in a product, an acknowledgment in the product documentation would be
15 ** appreciated but is not required.
16 ** 2. Altered source versions must be plainly marked as such, and must not be
17 ** misrepresented as being the original software.
18 ** 3. This notice may not be removed or altered from any source distribution.
19 **
20 ** Created on: 2022-02-10T18:13:51+01:00
21 ** Author: Sylvain Fargier <sfargier> <sylvain.fargier@cern.ch>
22 **
23 */
24 
25 #ifndef GRBL_PLATFORM_HPP__
26 #define GRBL_PLATFORM_HPP__
27 
28 #include <chrono>
29 #include <cstdint>
30 #include <functional>
31 #include <map>
32 #include <memory>
33 #include <mutex>
34 
35 #include <queue>
36 
37 #include <ccut/Queue.hpp>
38 #include <ccut/Thread.hpp>
39 #include <ccut/yml.hpp>
40 
41 #include "GrblAxis.hpp"
42 #include "GrblGpio.hpp"
43 #include "GrblTrigger.hpp"
44 #include "platform/PlatformBase.hpp"
45 #include "util/grbl/GrblParser.hpp"
46 #include "util/grbl/GrblTypes.hpp"
47 
48 namespace grbl {
49 class GrblDeviceBase;
50 }
51 
52 namespace smc {
53 namespace internal {
59 class MGrblPlatform;
60 class MFEPlatform;
61 
62 class GrblPlatform : public PlatformBase, public ccut::Thread
63 {
64 public:
65  typedef std::shared_ptr<GrblPlatform> Shared;
66 
67  typedef std::size_t Line;
68  struct LocalSettingHandler;
69 
70  typedef std::map<std::string, LocalSettingHandler> LocalSettingMap;
71 
72  struct AxisData;
73 
74  typedef std::map<std::string, grbl::GrblParser::SettingDesc> SettingMap;
75 
76  struct Context;
77  struct ImmediateCmd;
78  struct MotionCmd;
79 
84  static inline PlatformBase::Shared create(const ccut::yml::NodeRef &config)
85  {
86  return PlatformBase::Shared(new GrblPlatform(config));
87  }
88 
89  virtual ~GrblPlatform();
90 
91  inline std::shared_ptr<GrblPlatform> shared_from_this()
92  {
93  return std::static_pointer_cast<GrblPlatform>(
94  PlatformBase::shared_from_this());
95  }
96 
97  inline std::shared_ptr<const GrblPlatform> shared_from_this() const
98  {
99  return std::static_pointer_cast<const GrblPlatform>(
100  PlatformBase::shared_from_this());
101  }
102 
103  /* PlatformBase */
104  DeviceTypeList getSupportedDevices() const override;
105  DeviceList generateDevices(const DeviceTypeList &deviceType) override;
106 
107  void stop() override;
108  void wake() override;
109 
110  static const std::chrono::milliseconds defaultInterval;
111 
112  std::future<void> queue(MotionCmd &&);
113  template<typename T>
114  std::future<T> run(std::function<void(ImmediateCmd &, Context &)> fun);
115 
125  std::future<void> send(const std::string &cmd,
126  std::function<bool(const std::string &)> msg = {},
127  const std::chrono::milliseconds &timeout =
128  std::chrono::milliseconds{1000});
129 
130  void updateAxisSetting(const std::string &axis,
131  grbl::SettingId settingId,
132  const std::string &value);
133  units::Value getLastAxisPosition(const std::string &axis) const;
134  units::Value getLastAxisResolution(const std::string &axis) const;
135 
136  uint8_t getTrigger(const std::string &uid);
137  uint8_t getGpio(const std::string &uid);
138  grbl::Axis getAxis(const std::string &uid);
139  void clearQueues(const std::string &msg, bool clearImmediates = true);
140 
141  static const std::string s_loggerCat;
142 
143 protected:
144  friend class MGrblPlatform;
145  friend class MFEPlatform;
146  explicit GrblPlatform(const ccut::yml::NodeRef &node);
147 
149  AxisData &_getAxisData(const std::string &uid);
150 
151  mutable std::mutex m_lock;
152  std::queue<MotionCmd> m_queue;
153  std::queue<ImmediateCmd> m_immediate;
154  std::queue<MotionCmd> m_pending;
155  std::map<std::string, AxisData> m_axisMap;
156  std::pair<std::string, uint8_t> m_trigger;
157  std::map<std::string, uint8_t> m_gpioMap;
158  ccut::Connection m_dataConn;
159 
160  std::unique_ptr<Context> m_ctx;
161 
169  explicit GrblPlatform(const std::string &prefix,
170  const std::string &id,
171  std::unique_ptr<grbl::GrblDeviceBase> &&device);
172 
173  /* those methods are called from `thread_func` and may access `m_ctx` */
174  void processMessage(const std::string &message);
175  bool processMotion();
176  bool processImmediate();
177  void onStateMessage();
178  void loadErrors();
179  void loadAlarms();
180  void loadSettingsDesc();
181  void setup();
182  void handleAlarm();
183 
184  void generateGpios(const Context &ctx,
185  const std::list<grbl::GrblParser::PinInfo> &pins,
186  std::list<GrblGpio::Shared> &out);
187  void generateTriggers(Context &ctx,
188  const std::list<grbl::GrblParser::PinInfo> &pins,
189  std::list<GrblTrigger::Shared> &out);
190  void generateAxes(const Context &ctx,
191  size_t axesCount,
192  std::list<GrblAxis::Shared> &out);
193 
194  void thread_func() override;
195 
196  static constexpr std::size_t maxQueueSize = 1024;
197 };
198 
201 } // namespace internal
202 } // namespace smc
203 
204 #include "GrblPlatform.hxx"
205 
206 #endif
AxisData & _getAxisData(const std::string &uid)
static PlatformBase::Shared create(const ccut::yml::NodeRef &config)
Create new instance of MockPlatform and return shared_ptr owning it.
std::future< void > send(const std::string &cmd, std::function< bool(const std::string &)> msg={}, const std::chrono::milliseconds &timeout=std::chrono::milliseconds{1000})
send command to grbl
main motion-lib namespace
Definition: Client.cpp:30