MotionLib  1.0.0
SamBuCa motion library
MGrblPlatform.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-04-28T14:19:16+02:00
21 ** Author: Sylvain Fargier <sfargier> <sylvain.fargier@cern.ch>
22 **
23 */
24 
25 #ifndef MGRBL_PLATFORM_HPP__
26 #define MGRBL_PLATFORM_HPP__
27 
28 #include <future>
29 #include <memory>
30 #include <string>
31 
32 #include <ccut/Queue.hpp>
33 #include <ccut/Thread.hpp>
34 #include <ccut/yml.hpp>
35 
36 #include "MGrblAxis.hpp"
37 #include "MGrblGpio.hpp"
38 #include "MGrblTrigger.hpp"
39 #include "platform/PlatformBase.hpp"
40 #include "platform/specialized/GrblPlatform/GrblPlatform.hpp"
41 #include "util/grbl/MGrblParser.hpp"
42 
43 namespace smc {
44 
45 class Axis;
46 
47 namespace internal {
53 class MGrblPlatform : public PlatformBase, public ccut::Thread
54 {
55 public:
56  typedef std::shared_ptr<MGrblPlatform> Shared;
57 
58  struct Context;
59  struct ImmediateCmd;
60 
66  static inline PlatformBase::Shared create(const ccut::yml::NodeRef &config)
67  {
68  return PlatformBase::Shared(new MGrblPlatform(config));
69  }
70 
71  virtual ~MGrblPlatform();
72 
73  inline std::shared_ptr<MGrblPlatform> shared_from_this()
74  {
75  return std::static_pointer_cast<MGrblPlatform>(
76  PlatformBase::shared_from_this());
77  }
78 
79  inline std::shared_ptr<const MGrblPlatform> shared_from_this() const
80  {
81  return std::static_pointer_cast<const MGrblPlatform>(
82  PlatformBase::shared_from_this());
83  }
84 
85  /* PlatformBase */
86  DeviceTypeList getSupportedDevices() const override;
87  DeviceList generateDevices(const DeviceTypeList &deviceType) override;
88  void setNotificationWorker(const NotificationWorker::Shared &worker) override;
89 
93  std::future<mgrbl::Layout> getLayout();
94 
95  void stop() override;
96  void wake() override;
97 
102  void updateInstance(MGrblGpio &gpio) const;
103 
108  void updateInstance(MGrblAxis &axis) const;
109 
114  void updateInstance(MGrblTrigger &trigger) const;
115 
116  inline const std::string &mainTriggerUrl() const
117  {
118  return m_mainTriggerUrl;
119  }
120 
126  std::shared_ptr<GrblPlatform> getFirstInstance() const;
127 
132  inline std::shared_ptr<GrblPlatform> getInstance(
133  mgrbl::Instance instance) const
134  {
135  std::lock_guard<std::mutex> guard(m_lock);
136  if (instance >= m_platforms.size())
137  throw Exception(ErrorCode::InternalError,
138  "axis not bound to an instance");
139  else
140  return m_platforms[instance];
141  }
142 
149  void runOnInstance(Context &ctx,
150  std::function<void(GrblPlatform::Shared &platform,
151  GrblPlatform::Context &ctx)> fun,
152  bool onlyFirst = false) const;
153 
154  template<typename T>
155  std::future<T> run(std::function<void(ImmediateCmd &, Context &)> fun);
156 
157  void loadLayout(Context &ctx);
158  void getBuildInfo(Context &ctx);
159 
160 protected:
167  explicit MGrblPlatform(const ccut::yml::NodeRef &node,
168  Context *data = nullptr);
169 
170  void processMessage(const std::string &message);
171 
172  virtual MGrblAxis::Shared createAxis(
173  const std::string &uid,
174  const std::shared_ptr<GrblPlatform> &grbl);
175 
176  void thread_func() override;
177 
183  virtual void processUpdate(Context &ctx);
184  bool processImmediate(Context &ctx);
185  void createPlatforms(Context &ctx);
186  void clearQueue(const std::string &msg);
187 
188  inline std::vector<std::shared_ptr<GrblPlatform>> getPlatforms() const
189  {
190  std::lock_guard<std::mutex> guard(m_lock);
191  return m_platforms;
192  }
193 
194  std::unique_ptr<Context> m_ctx;
195 
196  mutable std::mutex m_lock;
197  std::vector<std::shared_ptr<GrblPlatform>> m_platforms;
198  std::map<std::string, std::size_t> m_triggers;
199  std::map<std::string, std::size_t> m_gpios;
200  const std::string m_mainTriggerUrl;
201  mgrbl::Layout m_layout;
202  ccut::Connection m_dataConn;
203  std::queue<ImmediateCmd> m_immediate;
204 };
205 
208 } // namespace internal
209 } // namespace smc
210 
211 #include "MGrblPlatformData.hpp"
212 
213 #endif
Exception thrown by MotionController in case of issues with command.
Definition: Exception.hpp:61
std::future< mgrbl::Layout > getLayout()
retrieve current layout
std::shared_ptr< GrblPlatform > getFirstInstance() const
return first instance
void runOnInstance(Context &ctx, std::function< void(GrblPlatform::Shared &platform, GrblPlatform::Context &ctx)> fun, bool onlyFirst=false) const
run the given lambda on all grbl sub-platforms
virtual void processUpdate(Context &ctx)
device status update function
MGrblPlatform(const ccut::yml::NodeRef &node, Context *data=nullptr)
internal constructor to use this as a sub-platform (MGrblPlatform)
static PlatformBase::Shared create(const ccut::yml::NodeRef &config)
Create new instance of MGrblPlatform and return shared_ptr owning it.
std::shared_ptr< GrblPlatform > getInstance(mgrbl::Instance instance) const
get instance related to the given axis
void updateInstance(MGrblGpio &gpio) const
update instance ptr related to the given gpio
main motion-lib namespace
Definition: Client.cpp:30