This commit is contained in:
Timur A. Fatkhullin 2025-10-01 06:26:50 +03:00
parent 0b7261a431
commit 3d769d79eb
8 changed files with 505 additions and 26 deletions

View File

@ -40,4 +40,14 @@ set(ASIBFM700_LIB asibfm700mount)
add_library(${ASIBFM700_LIB} STATIC ${ASIBFM700_LIB_SRC} add_library(${ASIBFM700_LIB} STATIC ${ASIBFM700_LIB_SRC}
asibfm700_mount.h asibfm700_mount.cpp asibfm700_mount.h asibfm700_mount.cpp
asibfm700_configfile.h) asibfm700_configfile.h)
target_link_libraries(${ASIBFM700_LIB} PRIVATE mcc) target_link_libraries(${ASIBFM700_LIB} PRIVATE mcc spdlog)
option(WITH_TESTS "Build tests" ON)
if (WITH_TESTS)
set(CFG_TEST_APP cfg_test)
add_executable(${CFG_TEST_APP} tests/cfg_test.cpp)
target_link_libraries(${CFG_TEST_APP} PRIVATE mcc)
enable_testing()
endif()

View File

@ -26,7 +26,7 @@ typedef mcc::utils::MccSpdlogLogger Asibfm700Logger;
/* MOUNT CONFIGURATION CLASS */ /* MOUNT CONFIGURATION CLASS */
struct Asibfm700MountConfig { struct Asibfm700MountConfig1 {
std::chrono::milliseconds hardwarePollingPeriod{100}; // main cycle period std::chrono::milliseconds hardwarePollingPeriod{100}; // main cycle period
// CCTE-related configuration // CCTE-related configuration

View File

@ -8,9 +8,13 @@
#include <unordered_map> #include <unordered_map>
#include <mcc_angle.h> #include <mcc_angle.h>
#include <mcc_moving_model_common.h>
#include <mcc_pcm.h> #include <mcc_pcm.h>
#include <mcc_utils.h> #include <mcc_utils.h>
#include "asibfm700_common.h"
#include "asibfm700_servocontroller.h"
namespace asibfm700 namespace asibfm700
{ {
@ -306,11 +310,15 @@ static auto Asibfm700MountConfigDefaults = std::make_tuple(
simple_config_record_t{"pcmBsplineDegree", std::vector<size_t>{3, 3}}, simple_config_record_t{"pcmBsplineDegree", std::vector<size_t>{3, 3}},
// PCM B-spline knots along X-axis (HA-angle or azimuth). By default from 0 to 2*PI radians // PCM B-spline knots along X-axis (HA-angle or azimuth). By default from 0 to 2*PI radians
// NOTE: The first and last values are interpretated as border knots!!!
// Thus the array length must be equal to or greater than 2!
simple_config_record_t{"pcmBsplineXknots", simple_config_record_t{"pcmBsplineXknots",
std::vector<double>{0.0, 0.6981317, 1.3962634, 2.0943951, 2.7925268, 3.4906585, 4.1887902, std::vector<double>{0.0, 0.6981317, 1.3962634, 2.0943951, 2.7925268, 3.4906585, 4.1887902,
4.88692191, 5.58505361, 6.28318531}}, 4.88692191, 5.58505361, 6.28318531}},
// PCM B-spline knots along Y-axis (declination or zenithal distance). By default from -PI/6 to PI/2 radians // PCM B-spline knots along Y-axis (declination or zenithal distance). By default from -PI/6 to PI/2 radians
// NOTE: The first and last values are interpretated as border knots!!!
// Thus the array length must be equal to or greater than 2!
simple_config_record_t{"pcmBsplineYknots", simple_config_record_t{"pcmBsplineYknots",
std::vector<double>{-0.52359878, -0.29088821, -0.05817764, 0.17453293, 0.40724349, std::vector<double>{-0.52359878, -0.29088821, -0.05817764, 0.17453293, 0.40724349,
0.63995406, 0.87266463, 1.10537519, 1.33808576, 1.57079633}}, 0.63995406, 0.87266463, 1.10537519, 1.33808576, 1.57079633}},
@ -324,8 +332,8 @@ static auto Asibfm700MountConfigDefaults = std::make_tuple(
/* slewing and tracking parameters */ /* slewing and tracking parameters */
// arcseconds per second // // arcseconds per second
simple_config_record_t{"sideralRate", 15.0410686}, // simple_config_record_t{"sideralRate", 15.0410686},
// timeout for telemetry updating in milliseconds // timeout for telemetry updating in milliseconds
simple_config_record_t{"telemetryTimeout", std::chrono::milliseconds(3000)}, simple_config_record_t{"telemetryTimeout", std::chrono::milliseconds(3000)},
@ -375,11 +383,59 @@ static auto Asibfm700MountConfigDefaults = std::make_tuple(
/* hardware-related */ /* hardware-related */
// hardware mode: 1 - model mode, otherwise real mode
simple_config_record_t{"RunModel", 0},
// mount serial device paths
simple_config_record_t{"MountDevPath", std::string("/dev/ttyUSB0")},
// mount serial device speed
simple_config_record_t{"MountDevSpeed", 19200},
// motor encoders serial device path
simple_config_record_t{"EncoderDevPath", std::string("")},
// X-axis encoder serial device path
simple_config_record_t{"EncoderXDevPath", std::string("/dev/encoderX0")},
// Y-axis encoder serial device path
simple_config_record_t{"EncoderYDevPath", std::string("/dev/encoderY0")},
// encoders serial device speed
simple_config_record_t{"EncoderDevSpeed", 153000},
// ==1 if encoder works as separate serial device, ==2 if there's new version with two devices
simple_config_record_t{"SepEncoder", 2},
// mount polling interval in millisecs
simple_config_record_t{"MountReqInterval", std::chrono::milliseconds(100)},
// encoders polling interval in millisecs
simple_config_record_t{"EncoderReqInterval", std::chrono::milliseconds(50)},
// mount axes rate calculation interval in millisecs
simple_config_record_t{"EncoderSpeedInterval", std::chrono::milliseconds(100)},
// X-axis coordinate PID P,I,D-params
simple_config_record_t{"XPIDC", std::vector<double>{0.8, 0.1, 0.3}},
// X-axis rate PID P,I,D-params
simple_config_record_t{"XPIDV", std::vector<double>{1.0, 0.01, 0.2}},
// Y-axis coordinate PID P, I, D-params
simple_config_record_t{"YPIDC", std::vector<double>{0.8, 0.1, 0.3}},
// Y-axis rate PID P,I,D-params
simple_config_record_t{"YPIDV", std::vector<double>{0.5, 0.2, 0.5}},
// maximal moving rate (degrees per second) along HA-axis (Y-axis of Sidereal servo microcontroller) // maximal moving rate (degrees per second) along HA-axis (Y-axis of Sidereal servo microcontroller)
simple_config_record_t{"hwMaxRateHA", mcc::MccAngle(5.0_degs)}, simple_config_record_t{"hwMaxRateHA", mcc::MccAngle(8.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{"hwMaxRateDEC", mcc::MccAngle(5.0_degs)} simple_config_record_t{"hwMaxRateDEC", mcc::MccAngle(10.0_degs)}
); );
@ -392,7 +448,10 @@ class Asibfm700MountConfig : protected ConfigHolder<decltype(Asibfm700MountConfi
public: public:
using base_t::value; using base_t::value;
Asibfm700MountConfig() : base_t(Asibfm700MountConfigDefaults) {} Asibfm700MountConfig() : base_t(Asibfm700MountConfigDefaults)
{
update();
}
~Asibfm700MountConfig() = default; ~Asibfm700MountConfig() = default;
@ -410,25 +469,243 @@ public:
buffer.resize(sz); buffer.resize(sz);
fst.read(buffer.data(), sz); fst.read(buffer.data(), sz);
} catch (std::ios_base::failure const& ex) {
return ex.code();
} catch (...) {
return std::make_error_code(std::errc::not_enough_memory);
}
fst.close(); fst.close();
} else {
return ec; ec = base_t::parse(buffer, deserializer);
if (!ec) {
update();
}
} catch (std::ios_base::failure const& ex) {
ec = ex.code();
} catch (std::length_error const& ex) {
ec = std::make_error_code(std::errc::no_buffer_space);
} catch (std::bad_alloc const& ex) {
ec = std::make_error_code(std::errc::not_enough_memory);
} catch (...) {
ec = std::make_error_code(std::errc::operation_canceled);
}
} }
return base_t::parse(buffer, deserializer); return ec;
} }
std::chrono::milliseconds hardwarePollingPeriod{};
mcc::MccAngle siteLatitude{};
mcc::MccAngle siteLongitude{};
double siteElevation{};
double refractWavelength{};
std::string leapSecondFilename{};
std::string bulletinAFilename{};
mcc::MccAngle pzMinAltitude{};
mcc::MccAngle pzLimitSwitchHAMin{};
mcc::MccAngle pzLimitSwitchHAMax{};
AsibFM700ServoController::hardware_config_t servoControllerConfig{};
mcc::MccSimpleMovingModelParams movingModelParams{};
Asibfm700PCM::pcm_data_t pcmData{};
protected: protected:
void update()
{
hardwarePollingPeriod = std::get<decltype(hardwarePollingPeriod)>(this->_configDB["hardwarePollingPeriod"]);
// CCTE
siteLatitude = std::get<mcc::MccAngle>(this->_configDB["siteLatitude"]);
siteLongitude = std::get<mcc::MccAngle>(this->_configDB["siteLongitude"]);
siteElevation = std::get<double>(this->_configDB["siteElevation"]);
refractWavelength = std::get<double>(this->_configDB["refractWavelength"]);
leapSecondFilename = std::get<std::string>(this->_configDB["leapSecondFilename"]);
bulletinAFilename = std::get<std::string>(this->_configDB["bulletinAFilename"]);
// prohibited zones
pzMinAltitude = std::get<mcc::MccAngle>(this->_configDB["pzMinAltitude"]);
pzLimitSwitchHAMin = std::get<mcc::MccAngle>(this->_configDB["pzLimitSwitchHAMin"]);
pzLimitSwitchHAMax = std::get<mcc::MccAngle>(this->_configDB["pzLimitSwitchHAMax"]);
// hardware config
servoControllerConfig.hwConfig = {};
servoControllerConfig.MountDevPath = std::get<std::string>(this->_configDB["MountDevPath"]);
servoControllerConfig.EncoderDevPath = std::get<std::string>(this->_configDB["EncoderDevPath"]);
servoControllerConfig.EncoderXDevPath = std::get<std::string>(this->_configDB["EncoderXDevPath"]);
servoControllerConfig.EncoderYDevPath = std::get<std::string>(this->_configDB["EncoderYDevPath"]);
servoControllerConfig.devConfig.MountDevPath = servoControllerConfig.MountDevPath.data();
servoControllerConfig.devConfig.EncoderDevPath = servoControllerConfig.EncoderDevPath.data();
servoControllerConfig.devConfig.EncoderXDevPath = servoControllerConfig.EncoderXDevPath.data();
servoControllerConfig.devConfig.EncoderYDevPath = servoControllerConfig.EncoderYDevPath.data();
servoControllerConfig.devConfig.RunModel = std::get<int>(this->_configDB["RunModel"]);
servoControllerConfig.devConfig.MountDevSpeed = std::get<int>(this->_configDB["MountDevSpeed"]);
servoControllerConfig.devConfig.EncoderDevSpeed = std::get<int>(this->_configDB["EncoderDevSpeed"]);
servoControllerConfig.devConfig.SepEncoder = std::get<int>(this->_configDB["SepEncoder"]);
std::chrono::duration<double> secs; // seconds as floating-point
secs = std::get<std::chrono::milliseconds>(this->_configDB["MountReqInterval"]);
servoControllerConfig.devConfig.MountReqInterval = secs.count();
secs = std::get<std::chrono::milliseconds>(this->_configDB["EncoderReqInterval"]);
servoControllerConfig.devConfig.EncoderReqInterval = secs.count();
secs = std::get<std::chrono::milliseconds>(this->_configDB["EncoderSpeedInterval"]);
servoControllerConfig.devConfig.EncoderSpeedInterval = secs.count();
std::vector<double> pid = std::get<std::vector<double>>(this->_configDB["XPIDC"]);
if (pid.size() > 2) {
servoControllerConfig.devConfig.XPIDC.P = pid[0];
servoControllerConfig.devConfig.XPIDC.I = pid[1];
servoControllerConfig.devConfig.XPIDC.D = pid[2];
}
pid = std::get<std::vector<double>>(this->_configDB["XPIDV"]);
if (pid.size() > 2) {
servoControllerConfig.devConfig.XPIDV.P = pid[0];
servoControllerConfig.devConfig.XPIDV.I = pid[1];
servoControllerConfig.devConfig.XPIDV.D = pid[2];
}
pid = std::get<std::vector<double>>(this->_configDB["YPIDC"]);
if (pid.size() > 2) {
servoControllerConfig.devConfig.YPIDC.P = pid[0];
servoControllerConfig.devConfig.YPIDC.I = pid[1];
servoControllerConfig.devConfig.YPIDC.D = pid[2];
}
pid = std::get<std::vector<double>>(this->_configDB["YPIDV"]);
if (pid.size() > 2) {
servoControllerConfig.devConfig.YPIDV.P = pid[0];
servoControllerConfig.devConfig.YPIDV.I = pid[1];
servoControllerConfig.devConfig.YPIDV.D = pid[2];
}
// slew and track parameters
movingModelParams.telemetryTimeout =
std::get<decltype(movingModelParams.telemetryTimeout)>(this->_configDB["telemetryTimeout"]);
movingModelParams.minTimeToPZone =
std::get<decltype(movingModelParams.minTimeToPZone)>(this->_configDB["minTimeToPZone"]);
movingModelParams.updatingPZoneInterval =
std::get<decltype(movingModelParams.updatingPZoneInterval)>(this->_configDB["updatingPZoneInterval"]);
movingModelParams.slewToleranceRadius =
std::get<decltype(movingModelParams.slewToleranceRadius)>(this->_configDB["slewToleranceRadius"]);
movingModelParams.adjustCoordDiff =
std::get<decltype(movingModelParams.adjustCoordDiff)>(this->_configDB["adjustCoordDiff"]);
movingModelParams.adjustCycleInterval =
std::get<decltype(movingModelParams.adjustCycleInterval)>(this->_configDB["adjustCycleInterval"]);
movingModelParams.slewTimeout =
std::get<decltype(movingModelParams.slewTimeout)>(this->_configDB["slewTimeout"]);
movingModelParams.timeShiftToTargetPoint =
std::get<decltype(movingModelParams.timeShiftToTargetPoint)>(this->_configDB["timeShiftToTargetPoint"]);
movingModelParams.trackingCycleInterval =
std::get<decltype(movingModelParams.trackingCycleInterval)>(this->_configDB["trackingCycleInterval"]);
// PCM data
pcmData.type = std::get<decltype(pcmData.type)>(this->_configDB["pcmType"]);
pcmData.siteLatitude = std::get<mcc::MccAngle>(this->_configDB["siteLatitude"]);
pid = std::get<std::vector<double>>(this->_configDB["pcmGeomCoeffs"]);
if (pid.size() >= 9) { // must be 9 coefficients
pcmData.geomCoefficients = {.zeroPointX = pid[0],
.zeroPointY = pid[1],
.collimationErr = pid[2],
.nonperpendErr = pid[3],
.misalignErr1 = pid[4],
.misalignErr2 = pid[5],
.tubeFlexure = pid[6],
.forkFlexure = pid[7],
.DECaxisFlexure = pid[8]};
}
std::vector<size_t> dd = std::get<decltype(dd)>(this->_configDB["pcmBsplineDegree"]);
if (dd.size() >= 2) {
pcmData.bspline.bsplDegreeX = dd[0] > 0 ? dd[0] : 3;
pcmData.bspline.bsplDegreeY = dd[1] > 0 ? dd[1] : 3;
}
pid = std::get<std::vector<double>>(this->_configDB["pcmBsplineXknots"]);
// pid must contains interior and border (single point for each border) knots so minimal length must be 2
if (pid.size() >= 2) {
// generate full knots array (with border knots)
size_t Nknots = pid.size() + pcmData.bspline.bsplDegreeX * 2 - 2;
pcmData.bspline.knotsX.resize(Nknots);
for (size_t i = 0; i <= pcmData.bspline.bsplDegreeX; ++i) { // border knots
pcmData.bspline.knotsX[i] = pid[0];
pcmData.bspline.knotsX[Nknots - i - 1] = pid.back();
}
for (size_t i = 0; i < (pid.size() - 2); ++i) { // interior knots
pcmData.bspline.knotsX[i + pcmData.bspline.bsplDegreeX] = pid[1 + i];
}
}
pid = std::get<std::vector<double>>(this->_configDB["pcmBsplineYknots"]);
// pid must contains interior and border (single point for each border) knots so minimal length must be 2
if (pid.size() >= 2) {
// generate full knots array (with border knots)
size_t Nknots = pid.size() + pcmData.bspline.bsplDegreeY * 2 - 2;
pcmData.bspline.knotsY.resize(Nknots);
for (size_t i = 0; i <= pcmData.bspline.bsplDegreeY; ++i) { // border knots
pcmData.bspline.knotsY[i] = pid[0];
pcmData.bspline.knotsY[Nknots - i - 1] = pid.back();
}
for (size_t i = 0; i < (pid.size() - 2); ++i) { // interior knots
pcmData.bspline.knotsY[i + pcmData.bspline.bsplDegreeY] = pid[1 + i];
}
}
// minimal allowed number of B-spline coefficients
size_t Ncoeffs = pcmData.type == mcc::MccDefaultPCMType::PCM_TYPE_GEOMETRY
? 0
: (pcmData.bspline.knotsX.size() - pcmData.bspline.bsplDegreeX - 1) *
(pcmData.bspline.knotsY.size() - pcmData.bspline.bsplDegreeY - 1);
pid = std::get<std::vector<double>>(this->_configDB["pcmBsplineXcoeffs"]);
if (pid.size() >= Ncoeffs) {
pcmData.bspline.coeffsX.resize(Ncoeffs);
for (size_t i = 0; i < Ncoeffs; ++i) {
pcmData.bspline.coeffsX[i] = pid[i];
}
}
pid = std::get<std::vector<double>>(this->_configDB["pcmBsplineYcoeffs"]);
if (pid.size() >= Ncoeffs) {
pcmData.bspline.coeffsY.resize(Ncoeffs);
for (size_t i = 0; i < Ncoeffs; ++i) {
pcmData.bspline.coeffsY[i] = pid[i];
}
}
}
inline static auto deserializer = [](std::string_view str, auto& value) { inline static auto deserializer = [](std::string_view str, auto& value) {
using value_t = std::decay_t<decltype(value)>; using value_t = std::decay_t<decltype(value)>;
bool ok; bool ok = true;
if constexpr (std::is_arithmetic_v<value_t> || std::ranges::output_range<value_t, char> || if constexpr (std::is_arithmetic_v<value_t> || std::ranges::output_range<value_t, char> ||
std::ranges::range<value_t>) { std::ranges::range<value_t>) {
@ -446,6 +723,22 @@ protected:
if (ok) { if (ok) {
value = mcc::MccAngle(vd, mcc::MccDegreeTag{}); value = mcc::MccAngle(vd, mcc::MccDegreeTag{});
} }
} else if constexpr (std::same_as<value_t, mcc::MccDefaultPCMType>) {
std::string vstr;
ok = base_t::defaultDeserializeFunc(str, vstr);
auto s = mcc::utils::trimSpaces(vstr);
if (ok) {
if (s == mcc::MccDefaultPCMTypeString<mcc::MccDefaultPCMType::PCM_TYPE_GEOMETRY>) {
value = mcc::MccDefaultPCMType::PCM_TYPE_GEOMETRY;
} else if (s == mcc::MccDefaultPCMTypeString<mcc::MccDefaultPCMType::PCM_TYPE_GEOMETRY_BSPLINE>) {
value = mcc::MccDefaultPCMType::PCM_TYPE_GEOMETRY;
} else if (s == mcc::MccDefaultPCMTypeString<mcc::MccDefaultPCMType::PCM_TYPE_BSPLINE>) {
value = mcc::MccDefaultPCMType::PCM_TYPE_BSPLINE;
} else {
return false;
}
}
} else { } else {
return false; return false;
} }
@ -454,4 +747,169 @@ protected:
}; };
}; };
static constexpr std::string_view Asibfm700MountConfigString =
R"--(
#
# ASTROSIB FM-700 MOUNT DEFAULT CONFIGURATION
#
# (created 2025-10-01T03:00:00.0)
#
# main cycle period
hardwarePollingPeriod = 100
# geographic coordinates of the observation site
# site latitude in degrees
siteLatitude = 43.646711
# site longitude in degrees
siteLongitude = 41.440732
# site elevation in meters
siteElevation = 2070.0
# celestial coordinate transformation
# wavelength at which refraction is calculated (in mkm)
refractWavelength = 0.55
# an empty filename means default precompiled string
leapSecondFilename =
# an empty filename means default precompiled string
bulletinAFilename =
# pointing correction model
# PCM default type
pcmType = GEOMETRY
# PCM geometrical coefficients
pcmGeomCoeffs = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
# PCM B-spline degrees
pcmBsplineDegree = 3, 3
# PCM B-spline knots along X-axis (HA-angle or azimuth). By default from 0 to 2*PI radians
pcmBsplineXknots = 0.0, 0.6981317, 1.3962634, 2.0943951, 2.7925268, 3.4906585, 4.1887902, 4.88692191, 5.58505361, 6.28318531
# PCM B-spline knots along Y-axis (declination or zenithal distance). By default from -PI/6 to PI/2 radians
pcmBsplineYknots = -0.52359878, -0.29088821, -0.05817764, 0.17453293, 0.40724349, 0.63995406, 0.87266463, 1.10537519, 1.33808576, 1.57079633
# PCM B-spline coeffs for along X-axis (HA-angle or azimuth)
pcmBsplineXcoeffs =
# PCM B-spline coeffs for along Y-axis (declination or zenithal distance)
pcmBsplineYcoeffs =
# slewing and tracking parameters
# arcseconds per second
#sideralRate = 15.0410686
# timeout for telemetry updating in milliseconds
telemetryTimeout = 3000
# minimal allowed time in seconds to prohibited zone
minTimeToPZone = 10
# a time interval to update prohibited zones related quantities (millisecs)
updatingPZoneInterval = 5000
# coordinates difference in arcsecs to stop slewing
slewToleranceRadius = 5.0
# target-mount coordinate difference in arcsecs to start adjusting of slewing
adjustCoordDiff = 50.0
# minimum time in millisecs between two successive adjustments
adjustCycleInterval = 300
# slew process timeout in seconds
slewTimeout = 3600
# a time shift into future to compute target position in future (UT1-scale time duration, millisecs)
timeShiftToTargetPoint = 10000
# minimum time in millisecs between two successive tracking corrections
trackingCycleInterval = 300
# prohibited zones
# minimal altitude in degrees
pzMinAltitude = 10.0
# HA-axis limit switch minimal value in degrees
pzLimitSwitchHAMin = -170.0
# HA-axis limit switch maximal value in degrees
pzLimitSwitchHAMax = 170.0
# DEC-axis limit switch minimal value in degrees
pzLimitSwitchDecMin = -90.0
# DEC-axis limit switch maximal value in degrees
pzLimitSwitchDecMax = 90.0
# hardware-related
# hardware mode: 1 - model mode, otherwise real mode
RunModel = 0
# mount serial device paths
MountDevPath = /dev/ttyUSB0
# mount serial device speed
MountDevSpeed = 19200
# motor encoders serial device path
EncoderDevPath =
# X-axis encoder serial device path
EncoderXDevPath = /dev/encoderX0
# Y-axis encoder serial device path
EncoderYDevPath = /dev/encoderY0
# encoders serial device speed
EncoderDevSpeed = 153000
# ==1 if encoder works as separate serial device, ==2 if there's new version with two devices
SepEncoder = 2
# mount polling interval in millisecs
MountReqInterval = 100
# encoders polling interval in millisecs
EncoderReqInterval = 50
# mount axes rate calculation interval in millisecs
EncoderSpeedInterval = 100
# X-axis coordinate PID P,I,D-params
XPIDC = 0.8, 0.1, 0.3
# X-axis rate PID P,I,D-params
XPIDV = 1.0, 0.01, 0.2
# Y-axis coordinate PID P,I,D-params
YPIDC = 0.8, 0.1, 0.3
# Y-axis rate PID P,I,D-params
YPIDV = 0.5, 0.2, 0.5
# maximal moving rate (degrees per second) along HA-axis (Y-axis of Sidereal servo microcontroller)
hwMaxRateHA = 8.0
# maximal moving rate (degrees per second) along DEC-axis (X-axis of Sidereal servo microcontroller)
hwMaxRateDEC = 10.0
)--";
} // namespace asibfm700 } // namespace asibfm700

View File

@ -125,6 +125,8 @@ Asibfm700Mount::error_t Asibfm700Mount::updateMountConfig(const Asibfm700MountCo
{ {
std::lock_guard lock{*_mountConfigMutex}; std::lock_guard lock{*_mountConfigMutex};
_mountConfig = cfg;
hardwareUpdateConfig(_mountConfig.servoControllerConfig.devConfig); hardwareUpdateConfig(_mountConfig.servoControllerConfig.devConfig);
hardwareUpdateConfig(_mountConfig.servoControllerConfig.hwConfig); hardwareUpdateConfig(_mountConfig.servoControllerConfig.hwConfig);

View File

@ -11,7 +11,7 @@
#include <mcc_tracking_model.h> #include <mcc_tracking_model.h>
#include "asibfm700_common.h" #include "asibfm700_common.h"
#include "asibfm700_configfile.h"
namespace asibfm700 namespace asibfm700

View File

@ -1,6 +1,6 @@
#include <iostream> #include <iostream>
#include "../../asibfm700/asibfm700_configfile.h" #include "../asibfm700_configfile.h"
template <typename VT> template <typename VT>
struct rec_t { struct rec_t {
@ -50,5 +50,18 @@ int main()
} }
std::cout << "]\n"; std::cout << "]\n";
std::ofstream fst("/tmp/cfg.cfg");
fst << asibfm700::Asibfm700MountConfigString;
fst.close();
asibfm700::Asibfm700MountConfig acfg;
auto ec = acfg.load("/tmp/cfg.cfg");
std::cout << "EC (load) = " << ec.message() << "\n";
std::cout << "refr w: " << acfg.refractWavelength << "\n";
return 0; return 0;
} }

View File

@ -92,9 +92,5 @@ if (WITH_TESTS)
target_include_directories(${CTTE_TEST_APP} PRIVATE ${ERFA_INCLUDE_DIR}) target_include_directories(${CTTE_TEST_APP} PRIVATE ${ERFA_INCLUDE_DIR})
target_link_libraries(${CTTE_TEST_APP} ERFA_LIB bsplines) target_link_libraries(${CTTE_TEST_APP} ERFA_LIB bsplines)
set(CFG_TEST_APP cfg_test)
add_executable(${CFG_TEST_APP} tests/cfg_test.cpp)
target_link_libraries(${CFG_TEST_APP} PRIVATE mcc)
enable_testing() enable_testing()
endif() endif()

View File

@ -21,7 +21,7 @@ struct MccSimpleMovingModelParams {
static constexpr double sideralRate = 15.0410686_arcsecs; // in radians per second static constexpr double sideralRate = 15.0410686_arcsecs; // in radians per second
// timeout to telemetry updating // timeout to telemetry updating
std::chrono::seconds telemetryTimeout{3}; std::chrono::milliseconds telemetryTimeout{3000};
// minimal time to prohibited zone (at current speed in slewing mode). if it is lesser then exit with error // minimal time to prohibited zone (at current speed in slewing mode). if it is lesser then exit with error
std::chrono::seconds minTimeToPZone{10}; std::chrono::seconds minTimeToPZone{10};
@ -60,7 +60,7 @@ struct MccSimpleMovingModelParams {
bool dualAxisTracking{true}; // mount must be of an equatorial type: false means guiding along only HA-axis bool dualAxisTracking{true}; // mount must be of an equatorial type: false means guiding along only HA-axis
// time shift into future to compute target position in future (UT1-scale time duration) // time shift into future to compute target position in future (UT1-scale time duration)
std::chrono::duration<double> timeShiftToTargetPoint{10.0}; std::chrono::milliseconds timeShiftToTargetPoint{10000};
// ******* guiding mode ******* // ******* guiding mode *******