...
This commit is contained in:
@@ -23,12 +23,33 @@
|
||||
namespace mcc
|
||||
{
|
||||
|
||||
// adaptor class for prohibited zones
|
||||
template <traits::mcc_mount_telemetry_data_c TelemetryDataT>
|
||||
struct MccPZoneWrapper {
|
||||
// a type to which the result of calling prohibited zone class methods 'timeTo' and 'timeFrom' will be converted
|
||||
typedef std::chrono::duration<double> pz_duration_t; // seconds as floating-point number
|
||||
|
||||
static constexpr pz_duration_t infiniteDuration{std::numeric_limits<double>::infinity()};
|
||||
static constexpr pz_duration_t zeroDuration{0.0};
|
||||
|
||||
typedef std::function<bool(const TelemetryDataT&)> pz_inzone_func_t;
|
||||
typedef std::function<pz_duration_t(const TelemetryDataT&)> pz_timeto_func_t;
|
||||
typedef std::function<pz_duration_t(const TelemetryDataT&)> pz_timefrom_func_t;
|
||||
|
||||
MccCoordPairKind coordPairKind;
|
||||
const std::function<std::string()> name;
|
||||
pz_inzone_func_t inZone;
|
||||
pz_timeto_func_t timeTo;
|
||||
pz_timefrom_func_t timeFrom;
|
||||
};
|
||||
|
||||
|
||||
template <traits::mcc_mount_controls_c MOUNT_CONTROLS>
|
||||
class MccMount : public fsm::MccFiniteStateMachine, public utils::MccSpdlogLogger, protected MOUNT_CONTROLS
|
||||
{
|
||||
// declare these classes as friends to allow them access protected members 'slewModel' and 'guidingModel'
|
||||
friend class MccMountStateSlew<MccMount<MOUNT_CONTROLS>>;
|
||||
friend class MccMountStateGuiding<MccMount<MOUNT_CONTROLS>>;
|
||||
// friend class MccMountStateSlew<MccMount<MOUNT_CONTROLS>>;
|
||||
// friend class MccMountStateGuiding<MccMount<MOUNT_CONTROLS>>;
|
||||
|
||||
public:
|
||||
typedef MOUNT_CONTROLS mount_controls_t;
|
||||
@@ -43,6 +64,47 @@ public:
|
||||
|
||||
// typedef typename slew_model_t::slew_params_t slew_params_t;
|
||||
|
||||
/* base classes for event and state */
|
||||
|
||||
class MccMountEventBase
|
||||
{
|
||||
protected:
|
||||
MccMount& _mount;
|
||||
|
||||
public:
|
||||
MccMountEventBase(MccMount& mount) : _mount(mount) {}
|
||||
virtual ~MccMountEventBase() = default;
|
||||
|
||||
MccMount& mount() { return _mount; }
|
||||
};
|
||||
|
||||
// The implementation of FSM (see mcc_finite_state_machine.h) requires
|
||||
// state to be a default constructible class, so one needs to hold
|
||||
// a pointer to mount class to guarantee access to its private or protected
|
||||
// members and methods
|
||||
class MccMountStateBase
|
||||
{
|
||||
protected:
|
||||
// a pointer to mount class to allow access to private/protected
|
||||
// members/methods of MccMount class from descendent state-classes.
|
||||
// the memory address can be obtained from a call of
|
||||
// MccMountEventBase::mount method (see above)
|
||||
MccMount* _mount;
|
||||
|
||||
public:
|
||||
MccMountStateBase() = default;
|
||||
|
||||
MccMountStateBase(const MccMountStateBase&) = delete;
|
||||
MccMountStateBase& operator=(const MccMountStateBase&) = delete;
|
||||
|
||||
// just as an example (ugly but I still cannot find a solution)
|
||||
// template <std::derived_from<MccMountEventBase> EvT>
|
||||
// void enter(EvT& event)
|
||||
// {
|
||||
// _mount = &event.mount();
|
||||
// _mount->forEachPZone(...);
|
||||
// }
|
||||
};
|
||||
|
||||
/* constructors and destructor */
|
||||
|
||||
@@ -64,6 +126,8 @@ public:
|
||||
logDebug("{}", std::string(r.begin(), r.end()));
|
||||
}
|
||||
|
||||
MccMount(const MccMount&) = delete;
|
||||
MccMount& operator=(const MccMount&) = delete;
|
||||
|
||||
virtual ~MccMount() { logDebug("Delete MccMount class instance: thread = {}", getThreadId()); }
|
||||
|
||||
@@ -103,15 +167,34 @@ public:
|
||||
{
|
||||
auto zone_ptr = std::make_shared<ZT>(std::move(zone));
|
||||
|
||||
using d_t = typename MccPZoneWrapper<mount_telemetry_data_t>::pz_duration_t;
|
||||
|
||||
_pzFuncs.emplace_back(
|
||||
{.coordPairKind = ZT::zoneCoordPairKind,
|
||||
.name = std::format("{}", zone_ptr->name()),
|
||||
.inZoneFunc = [zone_ptr,
|
||||
this](const mount_telemetry_data_t& tmry_data) { return zone_ptr->inZone(tmry_data); },
|
||||
.timeToFunc = [zone_ptr,
|
||||
this](const mount_telemetry_data_t& tmry_data) { return zone_ptr->timeTo(tmry_data); },
|
||||
.timeFromFunc =
|
||||
[zone_ptr, this](const mount_telemetry_data_t& tmry_data) { return zone_ptr->timeFrom(tmry_data); }});
|
||||
.name = [zone_ptr]() { return std::format("{}", zone_ptr->name()); },
|
||||
.inZone = [zone_ptr](const mount_telemetry_data_t& tmry_data) { return zone_ptr->inZone(tmry_data); },
|
||||
.timeTo =
|
||||
[zone_ptr](const mount_telemetry_data_t& tmry_data) {
|
||||
auto d = zone_ptr->timeTo(tmry_data);
|
||||
|
||||
if (d == ZT::infiniteDuration) {
|
||||
return MccPZoneWrapper<mount_telemetry_data_t>::infiniteDuration;
|
||||
} else if (d == ZT::zeroDuration) {
|
||||
return MccPZoneWrapper<mount_telemetry_data_t>::zeroDuration;
|
||||
}
|
||||
return std::chrono::duration_cast<d_t>(d);
|
||||
},
|
||||
.timeFrom =
|
||||
[zone_ptr](const mount_telemetry_data_t& tmry_data) {
|
||||
auto d = zone_ptr->timeFrom(tmry_data);
|
||||
|
||||
if (d == ZT::infiniteDuration) {
|
||||
return MccPZoneWrapper<mount_telemetry_data_t>::infiniteDuration;
|
||||
} else if (d == ZT::zeroDuration) {
|
||||
return MccPZoneWrapper<mount_telemetry_data_t>::zeroDuration;
|
||||
}
|
||||
return std::chrono::duration_cast<d_t>(d);
|
||||
}});
|
||||
|
||||
|
||||
if constexpr (sizeof...(ZTs)) {
|
||||
@@ -144,8 +227,8 @@ protected:
|
||||
pz_timefrom_func_t timeFromFunc;
|
||||
};
|
||||
|
||||
std::vector<pz_funcs_t> _pzFuncs{};
|
||||
|
||||
// std::vector<pz_funcs_t> _pzFuncs{};
|
||||
std::vector<MccPZoneWrapper<mount_telemetry_data_t>> _pzFuncs{};
|
||||
|
||||
template <typename FuncT, traits::mcc_prohibited_zone_c<mount_telemetry_data_t>... ZTs>
|
||||
auto forEachPZone(FuncT&& func, std::tuple<ZTs...>& zones)
|
||||
|
||||
Reference in New Issue
Block a user