Asibfm700Mount is now MccGenericMount (not MccGenericFsmMount)
fix mount initialization (add EEPROM reading, assign correponded mount config items) rewrite computing distance to pzones in slewing mode (add braking aceleration) add more informative errors description for serialization (network protocol)
This commit is contained in:
parent
9e8a7a62c9
commit
1c774d2d69
@ -15,13 +15,19 @@ Asibfm700Mount::Asibfm700Mount(Asibfm700MountConfig const& config, std::shared_p
|
||||
.lon = config.siteLongitude(),
|
||||
.elev = config.siteElevation()}),
|
||||
Asibfm700PCM(config.pcmData()),
|
||||
base_gm_class_t(Asibfm700StartState{},
|
||||
std::make_tuple(config.servoControllerConfig()),
|
||||
std::make_tuple(this),
|
||||
std::make_tuple(),
|
||||
std::make_tuple(this),
|
||||
std::make_tuple(this),
|
||||
std::make_tuple(logger, Asibfm700Logger::LOGGER_DEFAULT_FORMAT)),
|
||||
gm_class_t(std::make_tuple(config.servoControllerConfig()),
|
||||
std::make_tuple(this),
|
||||
std::make_tuple(),
|
||||
std::make_tuple(this),
|
||||
std::make_tuple(this),
|
||||
std::make_tuple(logger, Asibfm700Logger::LOGGER_DEFAULT_FORMAT)),
|
||||
// base_gm_class_t(Asibfm700StartState{},
|
||||
// std::make_tuple(config.servoControllerConfig()),
|
||||
// std::make_tuple(this),
|
||||
// std::make_tuple(),
|
||||
// std::make_tuple(this),
|
||||
// std::make_tuple(this),
|
||||
// std::make_tuple(logger, Asibfm700Logger::LOGGER_DEFAULT_FORMAT)),
|
||||
_mountConfig(config),
|
||||
_mountConfigMutex(new std::mutex)
|
||||
{
|
||||
@ -99,23 +105,6 @@ Asibfm700Mount::error_t Asibfm700Mount::initMount()
|
||||
|
||||
auto mpars = _mountConfig.movingModelParams();
|
||||
|
||||
logInfo("");
|
||||
logInfo("Setup slewing and tracking parameters ...");
|
||||
mpars.slewRateX = _mountConfig.getValue<mcc::MccAngle>("hwMaxRateHA").value_or(0.0);
|
||||
mpars.slewRateY = _mountConfig.getValue<mcc::MccAngle>("hwMaxRateDEC").value_or(0.0);
|
||||
auto st_err = setSlewingParams(mpars);
|
||||
if (st_err) {
|
||||
errorLogging(" An error occured while setting slewing parameters: ", st_err);
|
||||
} else {
|
||||
logInfo(" Max HA-axis speed: {} degs/s", mcc::MccAngle(mpars.slewRateX).degrees());
|
||||
logInfo(" Max DEC-axis speed: {} degs/s", mcc::MccAngle(mpars.slewRateY).degrees());
|
||||
}
|
||||
st_err = setTrackingParams(_mountConfig.movingModelParams());
|
||||
if (st_err) {
|
||||
errorLogging(" An error occured while setting tracking parameters: ", st_err);
|
||||
}
|
||||
logInfo("Slewing and tracking parameters have been set successfully");
|
||||
|
||||
using secs_t = std::chrono::duration<double>;
|
||||
auto to_msecs = [](double secs) {
|
||||
auto s = secs_t{secs};
|
||||
@ -147,13 +136,76 @@ Asibfm700Mount::error_t Asibfm700Mount::initMount()
|
||||
logInfo(" YPIDV: [P: {}, I: {}, D: {}]", hw_cfg.devConfig.YPIDV.P, hw_cfg.devConfig.YPIDV.I,
|
||||
hw_cfg.devConfig.YPIDV.D);
|
||||
|
||||
// auto hw_err = hardwareInit();
|
||||
// if (hw_err) {
|
||||
// errorLogging("", hw_err);
|
||||
// }
|
||||
// actually, only set this->_hardwareConfig.devConfig part and paths!!!
|
||||
this->_hardwareConfig = hw_cfg;
|
||||
|
||||
logInfo("");
|
||||
logInfo(" EEPROM data:");
|
||||
|
||||
if (hw_cfg.devConfig.RunModel != 1) { // load EEPROM only in REAL HARDWARE mode
|
||||
// load EEPROM part
|
||||
auto cfg_err = this->hardwareUpdateConfig();
|
||||
if (cfg_err) {
|
||||
errorLogging("Cannot load EEPROM data:", cfg_err);
|
||||
return cfg_err;
|
||||
}
|
||||
|
||||
mcc::MccAngle ang{_hardwareConfig.hwConfig.Yconf.accel}; // Sidereal defines HA-axis as Y-axis
|
||||
|
||||
logInfo(" HA-axis accel: {} degs/s^2", ang.degrees());
|
||||
ang = _hardwareConfig.hwConfig.Xconf.accel; // Sidereal defines DEC-axis as X-axis
|
||||
logInfo(" DEC-axis accel: {} degs/s^2", ang.degrees());
|
||||
logInfo(" HA-axis backlash: {}", (double)_hardwareConfig.hwConfig.Yconf.backlash);
|
||||
logInfo(" DEC-axis backlash: {}", (double)_hardwareConfig.hwConfig.Xconf.backlash);
|
||||
|
||||
logInfo(" HA-axis encoder ticks per revolution: {}",
|
||||
_hardwareConfig.hwConfig.Ysetpr); // Sidereal defines HA-axis as Y-axis
|
||||
logInfo(" DEC-axis encoder ticks per revolution: {}",
|
||||
_hardwareConfig.hwConfig.Xsetpr); // Sidereal defines DEC-axis as X-axis
|
||||
logInfo(" HA-motor encoder ticks per revolution: {}",
|
||||
_hardwareConfig.hwConfig.Ymetpr); // Sidereal defines HA-axis as Y-axis
|
||||
logInfo(" DEC-motor encoder ticks per revolution: {}",
|
||||
_hardwareConfig.hwConfig.Xmetpr); // Sidereal defines DEC-axis as X-axis
|
||||
|
||||
ang = _hardwareConfig.hwConfig.Yslewrate; // Sidereal defines HA-axis as Y-axis
|
||||
logInfo(" HA-axis slew rate: {} degs/s", ang.degrees());
|
||||
ang = _hardwareConfig.hwConfig.Xslewrate; // Sidereal defines DEC-axis as X-axis
|
||||
logInfo(" DEC-axis slew rate: {} degs/s", ang.degrees());
|
||||
} else {
|
||||
logWarn(" MODEL-MODE, no EEPROM data!");
|
||||
}
|
||||
|
||||
logInfo("");
|
||||
logInfo("Setup slewing and tracking parameters ...");
|
||||
mpars.slewRateX = _mountConfig.getValue<mcc::MccAngle>("hwMaxRateHA").value_or(0.0);
|
||||
mpars.slewRateY = _mountConfig.getValue<mcc::MccAngle>("hwMaxRateDEC").value_or(0.0);
|
||||
if (hw_cfg.devConfig.RunModel != 1) {
|
||||
mpars.brakingAccelX = _hardwareConfig.hwConfig.Yconf.accel; // Sidereal defines HA-axis as Y-axis
|
||||
mpars.brakingAccelY = _hardwareConfig.hwConfig.Xconf.accel; // Sidereal defines DEC-axis as X-axis
|
||||
} else {
|
||||
mpars.brakingAccelX = MCC_Y_ACCELERATION; // Sidereal defines HA-axis as Y-axis
|
||||
mpars.brakingAccelY = MCC_X_ACCELERATION; // Sidereal defines DEC-axis as X-axis
|
||||
}
|
||||
auto st_err = setSlewingParams(mpars);
|
||||
if (st_err) {
|
||||
errorLogging(" An error occured while setting slewing parameters: ", st_err);
|
||||
} else {
|
||||
logInfo(" Max HA-axis speed: {} degs/s", mcc::MccAngle(mpars.slewRateX).degrees());
|
||||
logInfo(" Max DEC-axis speed: {} degs/s", mcc::MccAngle(mpars.slewRateY).degrees());
|
||||
logInfo(" HA-axis stop acceleration braking: {} degs/s^2", mcc::MccAngle(mpars.brakingAccelX).degrees());
|
||||
logInfo(" DEC-axis stop acceleration braking: {} degs/s^2", mcc::MccAngle(mpars.brakingAccelY).degrees());
|
||||
}
|
||||
st_err = setTrackingParams(_mountConfig.movingModelParams());
|
||||
if (st_err) {
|
||||
errorLogging(" An error occured while setting tracking parameters: ", st_err);
|
||||
}
|
||||
logInfo("Slewing and tracking parameters have been set successfully");
|
||||
|
||||
|
||||
|
||||
// call base class initMount method
|
||||
auto hw_err = base_gm_class_t::initMount();
|
||||
auto hw_err = gm_class_t::initMount();
|
||||
// auto hw_err = base_gm_class_t::initMount();
|
||||
if (hw_err) {
|
||||
errorLogging("", hw_err);
|
||||
return hw_err;
|
||||
|
||||
@ -16,7 +16,63 @@ namespace asibfm700
|
||||
{
|
||||
|
||||
|
||||
class Asibfm700Mount : public Asibfm700CCTE,
|
||||
public Asibfm700PCM,
|
||||
public mcc::MccGenericMount<AsibFM700ServoController,
|
||||
mcc::MccTelemetry,
|
||||
Asibfm700PZoneContainer,
|
||||
mcc::MccSimpleSlewingModel,
|
||||
mcc::MccSimpleTrackingModel,
|
||||
Asibfm700Logger>
|
||||
{
|
||||
typedef mcc::MccGenericMount<AsibFM700ServoController,
|
||||
mcc::MccTelemetry,
|
||||
Asibfm700PZoneContainer,
|
||||
mcc::MccSimpleSlewingModel,
|
||||
mcc::MccSimpleTrackingModel,
|
||||
Asibfm700Logger>
|
||||
gm_class_t;
|
||||
|
||||
public:
|
||||
using gm_class_t::error_t;
|
||||
|
||||
using Asibfm700CCTE::setStateERFA;
|
||||
using Asibfm700CCTE::updateBulletinA;
|
||||
using Asibfm700CCTE::updateLeapSeconds;
|
||||
using Asibfm700CCTE::updateMeteoERFA;
|
||||
|
||||
using Asibfm700Logger::logCritical;
|
||||
using Asibfm700Logger::logDebug;
|
||||
using Asibfm700Logger::logError;
|
||||
using Asibfm700Logger::logInfo;
|
||||
using Asibfm700Logger::logWarn;
|
||||
|
||||
// using Asibfm700PZoneContainer::addPZone;
|
||||
|
||||
Asibfm700Mount(Asibfm700MountConfig const& config, std::shared_ptr<spdlog::logger> logger);
|
||||
|
||||
~Asibfm700Mount();
|
||||
|
||||
Asibfm700Mount(Asibfm700Mount&&) = default;
|
||||
Asibfm700Mount& operator=(Asibfm700Mount&&) = default;
|
||||
|
||||
Asibfm700Mount(const Asibfm700Mount&) = delete;
|
||||
Asibfm700Mount& operator=(const Asibfm700Mount&) = delete;
|
||||
|
||||
error_t initMount();
|
||||
|
||||
error_t updateMountConfig(Asibfm700MountConfig const&);
|
||||
Asibfm700MountConfig currentMountConfig();
|
||||
|
||||
protected:
|
||||
Asibfm700MountConfig _mountConfig;
|
||||
std::unique_ptr<std::mutex> _mountConfigMutex;
|
||||
|
||||
void errorLogging(const std::string&, const std::error_code&);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
class Asibfm700Mount : public Asibfm700CCTE,
|
||||
public Asibfm700PCM,
|
||||
public mcc::MccGenericFsmMount<mcc::MccGenericMount<AsibFM700ServoController,
|
||||
@ -118,6 +174,7 @@ protected:
|
||||
|
||||
void errorLogging(const std::string&, const std::error_code&);
|
||||
};
|
||||
*/
|
||||
|
||||
static_assert(mcc::mcc_position_controls_c<Asibfm700Mount>, "");
|
||||
static_assert(mcc::mcc_all_controls_c<Asibfm700Mount>, "");
|
||||
|
||||
@ -216,7 +216,7 @@ AsibFM700ServoController::error_t AsibFM700ServoController::hardwareUpdateConfig
|
||||
}
|
||||
|
||||
|
||||
AsibFM700ServoController::hardware_config_t AsibFM700ServoController::hardwareConfig() const
|
||||
AsibFM700ServoController::hardware_config_t AsibFM700ServoController::getHardwareConfig() const
|
||||
{
|
||||
return _hardwareConfig;
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ public:
|
||||
AsibFM700ServoController(AsibFM700ServoController&&) = default;
|
||||
AsibFM700ServoController& operator=(AsibFM700ServoController&&) = default;
|
||||
|
||||
~AsibFM700ServoController();
|
||||
virtual ~AsibFM700ServoController();
|
||||
|
||||
/* public methods */
|
||||
|
||||
@ -127,9 +127,9 @@ public:
|
||||
// load config from EEPROM
|
||||
error_t hardwareUpdateConfig();
|
||||
|
||||
hardware_config_t hardwareConfig() const;
|
||||
hardware_config_t getHardwareConfig() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
hardware_config_t _hardwareConfig;
|
||||
|
||||
std::unique_ptr<std::mutex> _setStateMutex;
|
||||
|
||||
@ -827,6 +827,17 @@ public:
|
||||
MccGenericFsmMount(StartStateT start_state, MountCtorArgTs&&... mount_ctor_args)
|
||||
: MOUNT_T(std::forward<MountCtorArgTs>(mount_ctor_args)...), fsm::MccFiniteStateMachine(std::move(start_state))
|
||||
{
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
this->logDebug(std::format("Create MccGenericFsmMount class instance ({})", this->getThreadId()));
|
||||
this->logDebug("MccGenericFsmMount finite-state machine states:");
|
||||
for (auto& el : stateIDs()) {
|
||||
this->logDebug(std::format(" {}", el));
|
||||
}
|
||||
this->logDebug("MccGenericFsmMount finite-state machine events:");
|
||||
for (auto& el : eventIDs()) {
|
||||
this->logDebug(std::format(" {}", el));
|
||||
}
|
||||
}
|
||||
}
|
||||
// template <fsm::traits::fsm_state_c ERROR_STATE_T = MccGenericFsmMountErrorState>
|
||||
// MccGenericFsmMount(MOUNT_T mount,
|
||||
@ -835,6 +846,19 @@ public:
|
||||
// {
|
||||
// }
|
||||
|
||||
MccGenericFsmMount(MccGenericFsmMount&&) = default;
|
||||
MccGenericFsmMount(const MccGenericFsmMount&) = delete;
|
||||
|
||||
MccGenericFsmMount& operator=(MccGenericFsmMount&&) = default;
|
||||
MccGenericFsmMount& operator=(const MccGenericFsmMount&) = delete;
|
||||
|
||||
virtual ~MccGenericFsmMount()
|
||||
{
|
||||
if constexpr (mcc_generic_log_mount_c<MOUNT_T>) {
|
||||
this->logDebug(std::format("Delete MccGenericFsmMount class instance ({})", this->getThreadId()));
|
||||
}
|
||||
}
|
||||
|
||||
// reimplementation of base-class methods to adapt it to FSM-behavior
|
||||
|
||||
error_t initMount()
|
||||
|
||||
@ -51,6 +51,11 @@ struct MccSimpleMovingModelParams {
|
||||
double adjustRateX{5.0_arcmins}; // maximal adjusting rate (a rate at the final slewing stage)
|
||||
double adjustRateY{5.0_arcmins}; // maximal adjusting rate (a rate at the final slewing stage)
|
||||
|
||||
// braking acceleration after execution of mount stopping command (in rads/s^2)
|
||||
// it must be given as non-negative value!!!
|
||||
double brakingAccelX{0.0};
|
||||
double brakingAccelY{0.0};
|
||||
|
||||
|
||||
// ******* tracking mode *******
|
||||
|
||||
@ -73,6 +78,46 @@ struct MccSimpleMovingModelParams {
|
||||
};
|
||||
|
||||
|
||||
// calculate the distances along the X and Y axes that the mount will travel at the current speed in a given time,
|
||||
// taking into account the braking acceleration
|
||||
//
|
||||
// WARNING:
|
||||
// It is assumed that the given braking accelerations are non-negative,
|
||||
// while speeds may have a sign according to motion direction.
|
||||
// The latter means that returned distances can be negative!
|
||||
std::pair<double, double> mcc_compute_distance(mcc_telemetry_data_c auto const& tdata,
|
||||
double time_in_secs,
|
||||
mcc_angle_c auto const& braking_accelX,
|
||||
mcc_angle_c auto const& braking_accelY)
|
||||
{
|
||||
std::pair<double, double> res;
|
||||
|
||||
// first, check if the mount will stop after given time_in_secs to prevent traveled path to be
|
||||
// negative
|
||||
//
|
||||
// the traveled path: s = V_ini*t - a*t*t/2, V_ini - initial speed, a - braking accel, t - the time
|
||||
// then, for s>=0, t <= 2*V_ini/a
|
||||
//
|
||||
|
||||
double term_x = 2.0 * std::abs(tdata.speedX) / braking_accelX;
|
||||
double term_y = 2.0 * std::abs(tdata.speedY) / braking_accelY;
|
||||
double tx = time_in_secs;
|
||||
double ty = time_in_secs;
|
||||
|
||||
if (std::isfinite(term_x) && (time_in_secs > term_x)) {
|
||||
tx = term_x;
|
||||
}
|
||||
if (std::isfinite(term_y) && (time_in_secs > term_y)) {
|
||||
ty = term_y;
|
||||
}
|
||||
|
||||
// here, one must take into account the sign of the speed!!!
|
||||
res.first = tdata.speedX * tx - std::copysign(braking_accelX, tdata.speedX) * tx * tx / 2.0;
|
||||
res.second = tdata.speedY * ty - std::copysign(braking_accelY, tdata.speedY) * ty * ty / 2.0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template <mcc_pzone_container_c PZoneContT>
|
||||
bool mcc_is_near_pzones(PZoneContT* pz_cont,
|
||||
mcc_telemetry_data_c auto const& tdata,
|
||||
|
||||
@ -589,7 +589,7 @@ public:
|
||||
std::expected<T, std::error_code> paramValue(size_t idx, DeserFuncT&& deser_func) const
|
||||
{
|
||||
if (idx >= _params.size()) {
|
||||
return std::unexpected{std::make_error_code(std::errc::argument_out_of_domain)};
|
||||
return std::unexpected{std::make_error_code(std::errc::value_too_large)};
|
||||
}
|
||||
|
||||
T val;
|
||||
@ -655,7 +655,7 @@ public:
|
||||
|
||||
auto r = valid_keys_t::isKeywordValid(key);
|
||||
if (!r) {
|
||||
return std::make_error_code(std::errc::argument_out_of_domain);
|
||||
return std::make_error_code(std::errc::not_supported);
|
||||
}
|
||||
|
||||
_keywordHash = *r;
|
||||
|
||||
@ -212,10 +212,28 @@ public:
|
||||
bool adjust_mode = false;
|
||||
static constexpr auto sideral_rate2 = slewing_params_t::sideralRate * slewing_params_t::sideralRate;
|
||||
|
||||
double braking_accelX, braking_accelY;
|
||||
{
|
||||
std::lock_guard lock{*_currentParamsMutex};
|
||||
if (mcc::utils::isEqual(_currentParams.brakingAccelX, 0.0)) {
|
||||
braking_accelX = std::numeric_limits<double>::min();
|
||||
} else {
|
||||
braking_accelX = std::abs(_currentParams.brakingAccelX);
|
||||
}
|
||||
|
||||
if (mcc::utils::isEqual(_currentParams.brakingAccelY, 0.0)) {
|
||||
braking_accelY = std::numeric_limits<double>::min();
|
||||
} else {
|
||||
braking_accelY = std::abs(_currentParams.brakingAccelY);
|
||||
}
|
||||
}
|
||||
|
||||
std::chrono::steady_clock::time_point start_slewing_tp, last_adjust_tp;
|
||||
start_slewing_tp = std::chrono::steady_clock::now();
|
||||
last_adjust_tp = start_slewing_tp;
|
||||
|
||||
std::pair<double, double> distXY;
|
||||
|
||||
// main loop (simply monitors the current position taking into account the prohibited zones, as well as the
|
||||
// timeout of the entire process)
|
||||
while (!*_stopSlewing) {
|
||||
@ -235,11 +253,16 @@ public:
|
||||
return MccSimpleSlewingModelErrorCode::ERROR_STOPPED;
|
||||
}
|
||||
|
||||
distXY = mcc_compute_distance(tdata, min_time_to_pzone_in_secs, braking_accelX, braking_accelY);
|
||||
|
||||
// calculate coordinates at current speed '_currentParams.minTimeToPZone' seconds ahead
|
||||
// and check them for getting into the prohibited zones
|
||||
if constexpr (mccIsEquatorialMount(CONTROLS_T::mountType)) {
|
||||
cpt.X = tdata.HA + tdata.speedX * min_time_to_pzone_in_secs;
|
||||
cpt.Y = tdata.DEC_APP + tdata.speedY * min_time_to_pzone_in_secs;
|
||||
cpt.X = tdata.HA + distXY.first;
|
||||
cpt.Y = tdata.DEC_APP + distXY.second;
|
||||
|
||||
// cpt.X = tdata.HA + tdata.speedX * min_time_to_pzone_in_secs;
|
||||
// cpt.Y = tdata.DEC_APP + tdata.speedY * min_time_to_pzone_in_secs;
|
||||
if (cpt.Y > DEG90INRADS) {
|
||||
cpt.Y = DEG90INRADS;
|
||||
}
|
||||
@ -247,8 +270,16 @@ public:
|
||||
cpt.Y = -DEG90INRADS;
|
||||
}
|
||||
} else if constexpr (mccIsAltAzMount(CONTROLS_T::mountType)) {
|
||||
cpt.X = tdata.AZ + tdata.speedX * min_time_to_pzone_in_secs;
|
||||
cpt.Y = tdata.ZD + tdata.speedY * min_time_to_pzone_in_secs;
|
||||
cpt.X = tdata.AZ + distXY.first;
|
||||
cpt.Y = tdata.ZD + distXY.second;
|
||||
// cpt.X = tdata.AZ + tdata.speedX * min_time_to_pzone_in_secs;
|
||||
// cpt.Y = tdata.ZD + tdata.speedY * min_time_to_pzone_in_secs;
|
||||
if (cpt.Y < 0.0) {
|
||||
cpt.Y = 0.0;
|
||||
}
|
||||
if (cpt.Y > std::numbers::pi) {
|
||||
cpt.Y = std::numbers::pi;
|
||||
}
|
||||
}
|
||||
mcc_tp2tp(tdata.time_point, cpt.time_point);
|
||||
|
||||
@ -384,6 +415,8 @@ public:
|
||||
// }
|
||||
}
|
||||
|
||||
*_stopSlewing = true;
|
||||
|
||||
return MccSimpleSlewingModelErrorCode::ERROR_OK;
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user