27 #include <ccut/async.hpp>
28 #include <logger/Logger.hpp>
30 #include "GrblAxis.hpp"
31 #include "GrblGpio.hpp"
32 #include "GrblPlatform.hpp"
33 #include "GrblPlatformDevice.hpp"
34 #include "device/Axis.hpp"
35 #include "platform/specialized/GrblPlatform/GrblTrigger.hpp"
36 #include "util/SettingParser.hpp"
37 #include "util/grbl/GrblDeviceBase.hpp"
38 #include "util/grbl/GrblGenerator.hpp"
39 #include "util/grbl/GrblParser.hpp"
41 using namespace logger;
42 using namespace std::chrono;
45 static const std::string s_resolutionSettingName{
"travel resolution"};
46 static const std::string s_loggerCat{
"smc:platform:grbl"};
51 PlatformBase::DeviceTypeList GrblPlatform::getSupportedDevices()
const
53 return DeviceTypeList{DeviceType::AXIS, DeviceType::TRIGGER,
54 DeviceType::GPIO, DeviceType::PLATFORM};
57 PlatformBase::DeviceList GrblPlatform::generateDevices(
58 const DeviceTypeList &deviceType)
61 if (deviceType.count(DeviceType::AXIS))
63 std::shared_ptr<GrblPlatform>
self(
64 std::static_pointer_cast<GrblPlatform>(shared_from_this()));
66 std::future<std::list<GrblAxis::Shared>> f =
67 run<std::list<GrblAxis::Shared>>(
69 std::list<GrblAxis::Shared> ret;
70 self->generateAxes(ctx, ctx.binfo.axisCount, ret);
71 cmd.prom->get<std::list<GrblAxis::Shared>>().set_value(ret);
73 if (f.wait_for(milliseconds(3000)) == std::future_status::timeout)
75 error(s_loggerCat) <<
"failed to generate Axes";
78 std::list<GrblAxis::Shared> axisList{f.get()};
79 for (GrblAxis::Shared axis : axisList)
82 axis->getConfig(s_resolutionSettingName).wait();
86 bool hasTriggers = deviceType.count(DeviceType::TRIGGER);
87 bool hasGpios = deviceType.count(DeviceType::GPIO);
88 if (hasTriggers || hasGpios)
90 std::shared_ptr<GrblPlatform>
self(
91 std::static_pointer_cast<GrblPlatform>(shared_from_this()));
93 std::future<std::list<DeviceBase::Shared>> f =
94 run<std::list<DeviceBase::Shared>>(
95 [
self, hasTriggers, hasGpios](
ImmediateCmd &cmd, Context &ctx) {
96 std::list<GrblParser::PinInfo> pinfo;
97 ctx.device->send(grbl::gen::System::EnumeratePins,
98 [&pinfo](
const std::string &line) {
99 return GrblParser::parsePinInfo(line,
102 std::list<DeviceBase::Shared> ret;
105 std::list<GrblGpio::Shared> gpios;
106 self->generateGpios(ctx, pinfo, gpios);
107 ret.insert(ret.end(), gpios.begin(), gpios.end());
111 std::list<GrblTrigger::Shared> triggers;
112 self->generateTriggers(ctx, pinfo, triggers);
113 ret.insert(ret.end(), triggers.begin(), triggers.end());
115 cmd.prom->get<std::list<DeviceBase::Shared>>().set_value(
119 if (f.wait_for(milliseconds(3000)) == std::future_status::timeout)
121 error(s_loggerCat) <<
"failed to generate Gpios and Triggers";
124 std::list<DeviceBase::Shared> devices{f.get()};
125 ret.insert(ret.end(), devices.begin(), devices.end());
127 if (deviceType.count(DeviceType::PLATFORM))
129 ret.emplace_back(
new GrblPlatformDevice{
130 m_ctx->prefix + m_ctx->id +
"/platform", shared_from_this()});
135 void GrblPlatform::generateTriggers(
137 const std::list<grbl::GrblParser::PinInfo> &pins,
138 std::list<GrblTrigger::Shared> &out)
140 const std::string platformUrl = ctx.prefix + ctx.id;
142 for (
const GrblParser::PinInfo &pinInfo : pins)
144 if (pinInfo.description ==
"Hardware Trigger")
146 const std::string url = platformUrl +
"/trigger";
147 out.emplace_back(
new GrblTrigger{url, shared_from_this()});
149 std::lock_guard<std::mutex> l(m_lock);
150 m_trigger.first = platformUrl;
151 m_trigger.second = pinInfo.pin;
155 ctx.localSetting[
"Triggered motion"] = {
156 [](Context &ctx,
const std::string &value) {
157 ctx.triggeredMotion = SettingParser::parse<bool>(value);
159 [](
const Context &ctx) -> std::string {
160 return ctx.triggeredMotion ?
"1" :
"0";
167 void GrblPlatform::generateGpios(
const Context &ctx,
168 const std::list<grbl::GrblParser::PinInfo> &pins,
169 std::list<GrblGpio::Shared> &out)
171 const std::string platformUrl = ctx.prefix + ctx.id;
173 for (
const GrblParser::PinInfo &pinInfo : pins)
175 if (pinInfo.description ==
"Pause/Resume")
177 const std::string url = platformUrl +
"/gpio/pauseResume";
178 out.emplace_back(
new GrblGpio{url, shared_from_this()});
180 std::lock_guard<std::mutex> l(m_lock);
181 m_gpioMap[url] = pinInfo.pin;
187 void GrblPlatform::generateAxes(
const Context &ctx,
189 std::list<GrblAxis::Shared> &out)
191 const std::string platformUrl = ctx.prefix + ctx.id +
"/axis/";
193 for (
size_t i = 0; i < axesCount; ++i)
195 const grbl::Axis grblAxis =
static_cast<grbl::Axis
>(i);
197 grbl::SettingId resolutionSettingId = -1;
200 resolutionSettingId =
201 ctx.findSetting(s_resolutionSettingName, grblAxis).id;
203 catch (
const Exception &ex)
205 logger::warning(s_loggerCat)
206 <<
"failed to retrieve " << s_resolutionSettingName <<
": "
210 out.emplace_back(
new GrblAxis{url, shared_from_this()});
212 std::lock_guard<std::mutex> l(m_lock);
213 m_axisMap[url] = AxisData{
214 grblAxis, units::value_t{units::mm, std::nan(
"initial value")},
216 units::value_t{units::STEPS_PER_MILLIMETER, -1.0}};
221 std::future<void> GrblPlatform::send(
const std::string &grblCmd,
222 std::function<
bool(
const std::string &)> msg,
223 const std::chrono::milliseconds &timeout)
227 grbl::ErrorCode rc = ctx.device->send(grblCmd, msg, timeout);
229 cmd.prom->get<
void>().set_value();
const std::string & to_string(Axis::State state)
convert State to string
main motion-lib namespace
void checkReply(grbl::ErrorCode code)
check command result code