This commit is contained in:
Timur A. Fatkhullin 2025-12-02 18:02:57 +03:00
parent bbf7314592
commit 7dfb0d5e9b
3 changed files with 114 additions and 56 deletions

View File

@ -261,7 +261,19 @@ static auto Asibfm700MountConfigDefaults = std::make_tuple(
simple_config_record_t{ simple_config_record_t{
"hwMaxRateDEC", "hwMaxRateDEC",
mcc::MccAngle(10.0_degs), mcc::MccAngle(10.0_degs),
{"maximal moving rate (degrees per second) along DEC-axis (X-axis of Sidereal servo microcontroller)"}} {"maximal moving rate (degrees per second) along DEC-axis (X-axis of Sidereal servo microcontroller)"}},
simple_config_record_t{"MaxPointingErr",
mcc::MccAngle(8.0_degs),
{"slewing-to-pointing mode angular limit in degrees"}},
simple_config_record_t{"MaxFinePointingErr",
mcc::MccAngle(1.5_degs),
{"pointing-to-guiding mode angular limit in degrees"}},
simple_config_record_t{"MaxGuidingErr",
mcc::MccAngle(0.5_arcsecs),
{"guiding 'good'-flag error cirle radius (mount-to-target distance) in arcsecs"}}
); );
@ -501,6 +513,16 @@ public:
hw_cfg.devConfig.YPIDV.D = pid[2]; hw_cfg.devConfig.YPIDV.D = pid[2];
} }
double ang = getValue<mcc::MccAngle>("MaxPointingErr").value_or(mcc::MccAngle(8.0_degs));
hw_cfg.devConfig.MaxPointingErr = ang;
ang = getValue<mcc::MccAngle>("MaxFinePointingErr").value_or(mcc::MccAngle(1.5_degs));
hw_cfg.devConfig.MaxFinePointingErr = ang;
ang = getValue<mcc::MccAngle>("MaxGuidingErr").value_or(mcc::MccAngle(0.5_arcsecs));
hw_cfg.devConfig.MaxGuidingErr = ang;
return hw_cfg; return hw_cfg;
} }

View File

@ -130,7 +130,8 @@ AsibFM700ServoController::error_t AsibFM700ServoController::hardwareSetState(har
// //
// according to the Eddy's implementation of the LibSidServo library it is safe // according to the Eddy's implementation of the LibSidServo library it is safe
// to pass the addresses of 'cvalpair' and 'cpair' automatic variables // to pass the addresses of 'cvalpair' and 'cpair' automatic variables
auto err = static_cast<AsibFM700ServoControllerErrorCode>(Mount.correctTo(&cvalpair, &cpair)); // auto err = static_cast<AsibFM700ServoControllerErrorCode>(Mount.correctTo(&cvalpair, &cpair));
auto err = static_cast<AsibFM700ServoControllerErrorCode>(Mount.correctTo(&cvalpair));
return err; return err;
} }

View File

@ -51,7 +51,10 @@ namespace mcc
struct MccSimpleSlewingModelCategory : public std::error_category { struct MccSimpleSlewingModelCategory : public std::error_category {
MccSimpleSlewingModelCategory() : std::error_category() {} MccSimpleSlewingModelCategory() : std::error_category() {}
const char* name() const noexcept { return "SIMPLE-SLEWING-MODEL"; } const char* name() const noexcept
{
return "SIMPLE-SLEWING-MODEL";
}
std::string message(int ec) const std::string message(int ec) const
{ {
@ -135,19 +138,28 @@ public:
MccTelemetryData tdata; MccTelemetryData tdata;
bool in_zone; bool in_zone;
std::vector<bool> in_zone_vec;
t_err = controls->telemetryData(&tdata); t_err = controls->telemetryData(&tdata);
if (t_err) { if (t_err) {
return mcc_deduce_error_code(t_err, MccSimpleSlewingModelErrorCode::ERROR_GET_TELEMETRY); return mcc_deduce_error_code(t_err, MccSimpleSlewingModelErrorCode::ERROR_GET_TELEMETRY);
} }
auto pz_err = controls->inPZone(tdata.target, &in_zone); auto pz_err = controls->inPZone(tdata.target, &in_zone, &in_zone_vec);
if (pz_err) { if (pz_err) {
return mcc_deduce_error_code(pz_err, MccSimpleSlewingModelErrorCode::ERROR_PZONE_CONTAINER_COMP); return mcc_deduce_error_code(pz_err, MccSimpleSlewingModelErrorCode::ERROR_PZONE_CONTAINER_COMP);
} }
if (in_zone) { if (in_zone) {
logger.logError("target point is in prohibited zone! Entered target coordinates:"); size_t i = 0;
for (; i < in_zone_vec.size(); ++i) {
if (in_zone_vec[i]) {
break;
}
}
logger.logError("target point is in prohibited zone (zone index: {})! Entered target coordinates:", i);
logger.logError(std::format(" RA-APP, DEC-APP, HA, LST: {}, {}, {}, {}", logger.logError(std::format(" RA-APP, DEC-APP, HA, LST: {}, {}, {}, {}",
mcc::MccAngle{tdata.target.RA_APP}.sexagesimal(true), mcc::MccAngle{tdata.target.RA_APP}.sexagesimal(true),
mcc::MccAngle{tdata.target.DEC_APP}.sexagesimal(), mcc::MccAngle{tdata.target.DEC_APP}.sexagesimal(),
@ -157,6 +169,10 @@ public:
mcc::MccAngle{tdata.target.ZD}.sexagesimal(), mcc::MccAngle{tdata.target.ZD}.sexagesimal(),
mcc::MccAngle{tdata.target.ALT}.sexagesimal())); mcc::MccAngle{tdata.target.ALT}.sexagesimal()));
logger.logError(std::format(" hardware X, Y: {}, {}", mcc::MccAngle{tdata.target.X}.sexagesimal(),
mcc::MccAngle{tdata.target.Y}.sexagesimal()));
return MccSimpleSlewingModelErrorCode::ERROR_TARGET_IN_PZONE; return MccSimpleSlewingModelErrorCode::ERROR_TARGET_IN_PZONE;
} }
@ -167,7 +183,41 @@ public:
// reset error // reset error
_lastError = MccSimpleSlewingModelErrorCode::ERROR_OK; _lastError = MccSimpleSlewingModelErrorCode::ERROR_OK;
// first, check target coordinates double braking_accelX, braking_accelY;
double min_time_to_pzone_in_secs;
{
// 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);
}
min_time_to_pzone_in_secs =
std::chrono::duration_cast<std::chrono::duration<double>>(_currentParams.minTimeToPZone).count();
}
logger.logInfo(
std::format("Start slewing in mode '{}'", (slew_and_stop ? "SLEW-AND-STOP" : "SLEW-AND-TRACK")));
logger.logInfo(std::format(" slewing process timeout: {} secs", _currentParams.slewTimeout.count()));
if (!slew_and_stop) {
logger.logInfo(std::format(" slewing tolerance radius: {} arcsecs",
mcc::MccAngle{_currentParams.slewToleranceRadius}.arcsecs()));
}
logger.logInfo(std::format(" braking acceleration X: {} degs/s^2 (in config: {} rads/s^2)",
mcc::MccAngle(braking_accelX).degrees(), _currentParams.brakingAccelX));
logger.logInfo(std::format(" braking acceleration Y: {} degs/s^2 (in config: {} rads/s^2)",
mcc::MccAngle(braking_accelY).degrees(), _currentParams.brakingAccelY));
logger.logInfo(std::format(" min time to prohibited zone: {} seconds", min_time_to_pzone_in_secs));
typename CONTROLS_T::error_t t_err; typename CONTROLS_T::error_t t_err;
MccTelemetryData tdata; MccTelemetryData tdata;
@ -185,6 +235,8 @@ public:
bool in_zone; bool in_zone;
std::vector<bool> in_zone_vec; std::vector<bool> in_zone_vec;
/*
auto pz_err = controls->inPZone(tdata.target, &in_zone, &in_zone_vec); auto pz_err = controls->inPZone(tdata.target, &in_zone, &in_zone_vec);
if (pz_err) { if (pz_err) {
*_stopSlewing = true; *_stopSlewing = true;
@ -221,38 +273,10 @@ public:
if (*_stopSlewing) { if (*_stopSlewing) {
return _lastError = MccSimpleSlewingModelErrorCode::ERROR_STOPPED; return _lastError = MccSimpleSlewingModelErrorCode::ERROR_STOPPED;
} }
*/
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);
}
}
logger.logInfo(
std::format("Start slewing in mode '{}'", (slew_and_stop ? "SLEW-AND-STOP" : "SLEW-AND-TRACK")));
logger.logInfo(std::format(" slewing process timeout: {} secs", _currentParams.slewTimeout.count()));
if (!slew_and_stop) {
logger.logInfo(std::format(" slewing tolerance radius: {} arcsecs",
mcc::MccAngle{_currentParams.slewToleranceRadius}.arcsecs()));
}
logger.logInfo(std::format(" braking acceleration X: {} degs/s^2 (in config: {} rads/s^2)",
mcc::MccAngle(braking_accelX).degrees(), _currentParams.brakingAccelX));
logger.logInfo(std::format(" braking acceleration Y: {} degs/s^2 (in config: {} rads/s^2)",
mcc::MccAngle(braking_accelY).degrees(), _currentParams.brakingAccelY));
MccCelestialPoint cpt; MccCelestialPoint cpt;
double min_time_to_pzone_in_secs;
if constexpr (mccIsEquatorialMount(CONTROLS_T::mountType)) { if constexpr (mccIsEquatorialMount(CONTROLS_T::mountType)) {
cpt.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP; cpt.pair_kind = MccCoordPairKind::COORDS_KIND_HADEC_APP;
@ -281,9 +305,6 @@ public:
hw_state.speedX = _currentParams.slewRateX; hw_state.speedX = _currentParams.slewRateX;
hw_state.speedY = _currentParams.slewRateY; hw_state.speedY = _currentParams.slewRateY;
min_time_to_pzone_in_secs =
std::chrono::duration_cast<std::chrono::duration<double>>(_currentParams.minTimeToPZone).count();
} }
hw_state.moving_state = CONTROLS_T::hardware_moving_state_t::HW_MOVE_SLEWING; hw_state.moving_state = CONTROLS_T::hardware_moving_state_t::HW_MOVE_SLEWING;
@ -319,12 +340,6 @@ public:
logger.logDebug(" the 'hardwareSetState' method performed successfully!"); logger.logDebug(" the 'hardwareSetState' method performed successfully!");
// std::chrono::steady_clock::time_point start_slewing_tp, last_adjust_tp;
// mcc_tp2tp(hw_state.time_point, start_slewing_tp); // not compiled!!
// double dist, dx, dy, sinY, rate2, xrate;
// std::chrono::duration<double> dtx, dty; // seconds in double
double dist, dx, dy; double dist, dx, dy;
// bool adjust_mode = false; // bool adjust_mode = false;
@ -524,18 +539,23 @@ public:
hw_state.X = (double)tdata.target.X; hw_state.X = (double)tdata.target.X;
hw_state.Y = (double)tdata.target.Y; hw_state.Y = (double)tdata.target.Y;
controls->targetToMountDiff(tdata.pair_kind, &dx, &dy); // controls->targetToMountDiff(tdata.pair_kind, &dx, &dy);
// hw_state.endptX = hw_state.X + std::copysign(1.0_degs, dx); // // hw_state.endptX = hw_state.X + std::copysign(1.0_degs, dx);
// hw_state.endptY = hw_state.Y + std::copysign(1.0_degs, dy); // // hw_state.endptY = hw_state.Y + std::copysign(1.0_degs, dy);
hw_state.endptX = hw_state.X + std::copysign(10.0_degs, dx); // hw_state.endptX = hw_state.X + std::copysign(10.0_degs, dx);
hw_state.endptY = hw_state.Y + std::copysign(10.0_degs, dy); // hw_state.endptY = hw_state.Y + std::copysign(10.0_degs, dy);
logger.logTrace(std::format( // logger.logTrace(std::format(
"Send to hardware: {}, {}, tag: {}, {} (X = {} degs, Y = {} degs)", // "Send to hardware: {}, {}, tag: {}, {} (X = {} degs, Y = {} degs)",
MccAngle(hw_state.X).sexagesimal(true), MccAngle(hw_state.Y).sexagesimal(), // MccAngle(hw_state.X).sexagesimal(true), MccAngle(hw_state.Y).sexagesimal(),
MccAngle(hw_state.endptX).sexagesimal(true), MccAngle(hw_state.endptY).sexagesimal(), // MccAngle(hw_state.endptX).sexagesimal(true), MccAngle(hw_state.endptY).sexagesimal(),
mcc::MccAngle{hw_state.X}.degrees(), mcc::MccAngle{hw_state.Y}.degrees())); // mcc::MccAngle{hw_state.X}.degrees(), mcc::MccAngle{hw_state.Y}.degrees()));
logger.logTrace(std::format("Send to hardware: {}, {}, (X = {} degs, Y = {} degs)",
MccAngle(hw_state.X).sexagesimal(true),
MccAngle(hw_state.Y).sexagesimal(), mcc::MccAngle{hw_state.X}.degrees(),
mcc::MccAngle{hw_state.Y}.degrees()));
hw_err = controls->hardwareSetState(hw_state); hw_err = controls->hardwareSetState(hw_state);
if (hw_err) { if (hw_err) {
@ -629,7 +649,18 @@ public:
*_stopSlewing = false; *_stopSlewing = false;
return _slewingFunc(slew_and_stop); // check for target in p-zone
_lastError = _checkTargetFunc();
if (_lastError) { // return here immidiately
return _lastError;
}
// asynchronous slewing process
_slewFuncFuture = std::async(std::launch::async, _slewingFunc, slew_and_stop);
return MccSimpleSlewingModelErrorCode::ERROR_OK;
// return _slewingFunc(slew_and_stop);
} }
@ -662,7 +693,10 @@ public:
return _currentParams; return _currentParams;
} }
error_t slewingLastError() const { return _lastError; } error_t slewingLastError() const
{
return _lastError;
}
protected: protected:
std::function<error_t(bool)> _slewingFunc{}; std::function<error_t(bool)> _slewingFunc{};
@ -673,6 +707,7 @@ protected:
std::unique_ptr<std::mutex> _currentParamsMutex{}; std::unique_ptr<std::mutex> _currentParamsMutex{};
error_t _lastError; error_t _lastError;
std::future<error_t> _slewFuncFuture{};
}; };