add PID-related items in mount config

rewrite AsibFM700ServoController methods according to new time point
representation in LibSidServo
This commit is contained in:
Timur A. Fatkhullin 2025-12-04 18:11:41 +03:00
parent da9cd51e5c
commit acd26edc9c
3 changed files with 87 additions and 4 deletions

View File

@ -238,6 +238,21 @@ static auto Asibfm700MountConfigDefaults = std::make_tuple(
std::chrono::milliseconds(100), std::chrono::milliseconds(100),
{"mount axes rate calculation interval in millisecs"}}, {"mount axes rate calculation interval in millisecs"}},
simple_config_record_t{"PIDMaxDt",
std::chrono::milliseconds(1000),
{"maximal PID refresh time interval in millisecs",
"NOTE: if PID data will be refreshed with interval longer than this value (e.g. user polls "
"encoder data too rarely)",
"then the PID 'expired' data will be cleared and new computing loop is started"}},
simple_config_record_t{"PIDRefreshDt", std::chrono::milliseconds(100), {"PID refresh interval"}},
simple_config_record_t{"PIDCycleDt",
std::chrono::milliseconds(5000),
{"PID I cycle time (analog of 'RC' for PID on opamps)"}},
// X-axis coordinate PID P,I,D-params // X-axis coordinate PID P,I,D-params
simple_config_record_t{"XPIDC", std::vector<double>{0.8, 0.1, 0.3}, {"X-axis coordinate PID P,I,D-params"}}, simple_config_record_t{"XPIDC", std::vector<double>{0.8, 0.1, 0.3}, {"X-axis coordinate PID P,I,D-params"}},
@ -485,6 +500,16 @@ public:
secs = getValue<std::chrono::milliseconds>("EncoderSpeedInterval").value_or(std::chrono::milliseconds{}); secs = getValue<std::chrono::milliseconds>("EncoderSpeedInterval").value_or(std::chrono::milliseconds{});
hw_cfg.devConfig.EncoderSpeedInterval = secs.count(); hw_cfg.devConfig.EncoderSpeedInterval = secs.count();
secs = getValue<std::chrono::milliseconds>("PIDMaxDt").value_or(std::chrono::milliseconds{1000});
hw_cfg.devConfig.PIDMaxDt = secs.count();
secs = getValue<std::chrono::milliseconds>("PIDRefreshDt").value_or(std::chrono::milliseconds{100});
hw_cfg.devConfig.PIDRefreshDt = secs.count();
secs = getValue<std::chrono::milliseconds>("PIDCycleDt").value_or(std::chrono::milliseconds{5000});
hw_cfg.devConfig.PIDCycleDt = secs.count();
std::vector<double> pid = getValue<std::vector<double>>("XPIDC").value_or(std::vector<double>{}); std::vector<double> pid = getValue<std::vector<double>>("XPIDC").value_or(std::vector<double>{});
if (pid.size() > 2) { if (pid.size() > 2) {
hw_cfg.devConfig.XPIDC.P = pid[0]; hw_cfg.devConfig.XPIDC.P = pid[0];

View File

@ -126,6 +126,9 @@ Asibfm700Mount::error_t Asibfm700Mount::initMount()
logInfo(" MountReqInterval: {}", to_msecs(hw_cfg.devConfig.MountReqInterval)); logInfo(" MountReqInterval: {}", to_msecs(hw_cfg.devConfig.MountReqInterval));
logInfo(" EncoderReqInterval: {}", to_msecs(hw_cfg.devConfig.EncoderReqInterval)); logInfo(" EncoderReqInterval: {}", to_msecs(hw_cfg.devConfig.EncoderReqInterval));
logInfo(" EncoderSpeedInterval: {}", to_msecs(hw_cfg.devConfig.EncoderSpeedInterval)); logInfo(" EncoderSpeedInterval: {}", to_msecs(hw_cfg.devConfig.EncoderSpeedInterval));
logInfo(" PIDMaxDt: {}", to_msecs(hw_cfg.devConfig.PIDMaxDt));
logInfo(" PIDRefreshDt: {}", to_msecs(hw_cfg.devConfig.PIDRefreshDt));
logInfo(" PIDCycleDt: {}", to_msecs(hw_cfg.devConfig.PIDCycleDt));
logInfo(" XPIDC: [P: {}, I: {}, D: {}]", hw_cfg.devConfig.XPIDC.P, hw_cfg.devConfig.XPIDC.I, logInfo(" XPIDC: [P: {}, I: {}, D: {}]", hw_cfg.devConfig.XPIDC.P, hw_cfg.devConfig.XPIDC.I,
hw_cfg.devConfig.XPIDC.D); hw_cfg.devConfig.XPIDC.D);
@ -186,6 +189,44 @@ Asibfm700Mount::error_t Asibfm700Mount::initMount()
mpars.brakingAccelX = 0.165806; // Sidereal defines HA-axis as Y-axis mpars.brakingAccelX = 0.165806; // Sidereal defines HA-axis as Y-axis
mpars.brakingAccelY = 0.219911; // Sidereal defines DEC-axis as X-axis mpars.brakingAccelY = 0.219911; // Sidereal defines DEC-axis as X-axis
} }
auto max_dt_intvl = _mountConfig.getValue<std::chrono::milliseconds>("PIDMaxDt").value_or({});
auto min_dt_intvl = _mountConfig.getValue<std::chrono::milliseconds>("PIDRefreshDt").value_or({});
// check for polling interval consistency
auto intvl = mpars.slewingTelemetryInterval;
if (intvl > max_dt_intvl) {
mpars.slewingTelemetryInterval = max_dt_intvl;
logWarn(
" slewingTelemetryInterval user value ({} ms) is greater than allowed! Set it to maximal "
"allowed one: {} ms",
intvl.count(), max_dt_intvl.count());
}
if (intvl < min_dt_intvl) {
mpars.slewingTelemetryInterval = min_dt_intvl;
logWarn(
" slewingTelemetryInterval user value ({} ms) is lesser than allowed! Set it to minimal allowed "
"one: {} ms",
intvl.count(), min_dt_intvl.count());
}
intvl = mpars.trackingTelemetryInterval;
if (intvl > max_dt_intvl) {
mpars.trackingTelemetryInterval = max_dt_intvl;
logWarn(
" trackingTelemetryInterval user value ({} ms) is greater than allowed! Set it to maximal "
"allowed one: {} ms",
intvl.count(), max_dt_intvl.count());
}
if (intvl < min_dt_intvl) {
mpars.trackingTelemetryInterval = min_dt_intvl;
logWarn(
" trackingTelemetryInterval user value ({} ms) is lesser than allowed! Set it to minimal "
"allowed one: {} ms",
intvl.count(), min_dt_intvl.count());
}
auto st_err = setSlewingParams(mpars); auto st_err = setSlewingParams(mpars);
if (st_err) { if (st_err) {
errorLogging(" An error occured while setting slewing parameters: ", st_err); errorLogging(" An error occured while setting slewing parameters: ", st_err);
@ -194,10 +235,14 @@ Asibfm700Mount::error_t Asibfm700Mount::initMount()
logInfo(" Max DEC-axis speed: {} degs/s", mcc::MccAngle(mpars.slewRateY).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(" 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()); logInfo(" DEC-axis stop acceleration braking: {} degs/s^2", mcc::MccAngle(mpars.brakingAccelY).degrees());
logInfo(" Slewing telemetry polling interval: {} millisecs", mpars.slewingTelemetryInterval.count());
} }
st_err = setTrackingParams(_mountConfig.movingModelParams()); st_err = setTrackingParams(_mountConfig.movingModelParams());
if (st_err) { if (st_err) {
errorLogging(" An error occured while setting tracking parameters: ", st_err); errorLogging(" An error occured while setting tracking parameters: ", st_err);
} else {
logInfo(" Tracking telemetry polling interval: {} millisecs", mpars.trackingTelemetryInterval.count());
} }
logInfo("Slewing and tracking parameters have been set successfully"); logInfo("Slewing and tracking parameters have been set successfully");

View File

@ -119,7 +119,14 @@ AsibFM700ServoController::error_t AsibFM700ServoController::hardwareSetState(har
// time point from sidservo library is 'double' number represented UNIXTIME with // time point from sidservo library is 'double' number represented UNIXTIME with
// microseconds/nanoseconds precision // microseconds/nanoseconds precision
double tp = std::chrono::duration<double>(state.time_point.time_since_epoch()).count(); // double tp = std::chrono::duration<double>(state.time_point.time_since_epoch()).count();
// 2025-12-04: coordval_pair_t.X.t is now of type struct timespec
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(state.time_point.time_since_epoch());
auto secs = std::chrono::floor<std::chrono::seconds>(ns);
ns -= secs;
std::timespec tp{.tv_sec = secs.count(), .tv_nsec = ns.count()};
// according to"SiTech protocol notes" X is DEC-axis and Y is HA-axis // according to"SiTech protocol notes" X is DEC-axis and Y is HA-axis
coordval_pair_t cvalpair{.X{.val = state.Y, .t = tp}, .Y{.val = state.X, .t = tp}}; coordval_pair_t cvalpair{.X{.val = state.Y, .t = tp}, .Y{.val = state.X, .t = tp}};
@ -151,10 +158,16 @@ AsibFM700ServoController::error_t AsibFM700ServoController::hardwareGetState(har
// time point from sidservo library is 'double' number represented UNIXTIME with // time point from sidservo library is 'double' number represented UNIXTIME with
// microseconds/nanoseconds precision (must be equal for encXposition and encYposition) // microseconds/nanoseconds precision (must be equal for encXposition and encYposition)
using secs_t = std::chrono::duration<double>; // using secs_t = std::chrono::duration<double>;
// secs_t secs = secs_t{mdata.encXposition.t};
// state->time_point = tp_t{std::chrono::duration_cast<tp_t::duration>(secs)};
// 2025-12-04: coordval_pair_t.X.t is now of type struct timespec
auto dr = std::chrono::duration_cast<decltype(state->time_point)::duration>(
std::chrono::seconds(mdata.encXposition.t.tv_sec) + std::chrono::nanoseconds(mdata.encXposition.t.tv_nsec));
state->time_point = decltype(state->time_point){dr};
secs_t secs = secs_t{mdata.encXposition.t};
state->time_point = tp_t{std::chrono::duration_cast<tp_t::duration>(secs)};
// if (mcc::utils::isEqual(secs.count(), 0.0)) { // model mode? // if (mcc::utils::isEqual(secs.count(), 0.0)) { // model mode?
// state->time_point = decltype(state->time_point)::clock::now(); // state->time_point = decltype(state->time_point)::clock::now();