...
This commit is contained in:
parent
a5bdf87a9b
commit
9e70ace4b7
@ -7,6 +7,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
option(USE_XSIMD "Use of XSIMD library to generate vectorized code" ON)
|
||||
|
||||
|
||||
find_package(ASIO QUIET)
|
||||
if (ASIO_FOUND)
|
||||
# message(STATUS "ASIO library was found")
|
||||
@ -69,6 +72,12 @@ endif()
|
||||
add_compile_definitions(SPDLOG_USE_STD_FORMAT)
|
||||
add_compile_definitions(SPDLOG_FMT_EXTERNAL=0)
|
||||
|
||||
if (USE_XSIMD)
|
||||
# fetch XSIMD library
|
||||
add_compile_definitions(VEC_XSIMD)
|
||||
endif()
|
||||
|
||||
|
||||
option(WITH_TESTS "Build tests" ON)
|
||||
|
||||
# Mount client-to-server communication protocol
|
||||
@ -85,7 +94,7 @@ set(CNTR_PROTO_LIB_SRC
|
||||
set(CNTR_PROTO_LIB comm_proto)
|
||||
add_library(${CNTR_PROTO_LIB} STATIC ${CNTR_PROTO_LIB_SRC})
|
||||
|
||||
set(MOUNT_SERVER_APP_SRC mount.h mount_server.cpp comm_server.h comm_server_endpoint.h)
|
||||
set(MOUNT_SERVER_APP_SRC mount.h mount_server.cpp comm_server.h comm_server_endpoint.h mount_astrom.h)
|
||||
set(MOUNT_SERVER_APP mount_server)
|
||||
add_executable(${MOUNT_SERVER_APP} ${MOUNT_SERVER_APP_SRC}
|
||||
comm_server_configfile.h)
|
||||
|
||||
55
cxx/mount.h
55
cxx/mount.h
@ -10,6 +10,7 @@
|
||||
#include <string_view>
|
||||
#include "spdlog/sinks/null_sink.h"
|
||||
|
||||
#include "mount_astrom.h"
|
||||
|
||||
// low-level functions
|
||||
namespace lowlevel
|
||||
@ -35,6 +36,60 @@ concept mcc_mount_state_c = requires(T t, const T t_const) {
|
||||
};
|
||||
|
||||
|
||||
class MccMountPosition
|
||||
{
|
||||
public:
|
||||
typedef double mnt_coord_t;
|
||||
typedef double mnt_speed_t;
|
||||
typedef double time_point_t;
|
||||
|
||||
// time-related
|
||||
std::chrono::system_clock::time_point utc;
|
||||
time_point_t mjd; // modified Julian date
|
||||
time_point_t ut1;
|
||||
time_point_t tt;
|
||||
time_point_t siderTime; // sideral time (in radians)
|
||||
|
||||
// apparent target (user-input) current coordinates (in radians)
|
||||
mnt_coord_t tagRA, tagDEC;
|
||||
mnt_coord_t tagHA;
|
||||
mnt_coord_t tagAZ, tagZD;
|
||||
|
||||
// encoder-measured current mount coordinates (in radians)
|
||||
mnt_coord_t mntRA, mntDEC;
|
||||
mnt_coord_t mntHA;
|
||||
mnt_coord_t mntAZ, mntZD;
|
||||
|
||||
// encoder-measured current mount moving speed (in radians/s)
|
||||
mnt_speed_t mntSpeedX,
|
||||
mntSpeedY; // X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ZD for horizontal-type one
|
||||
|
||||
// current refraction coefficient
|
||||
mnt_coord_t currRefr;
|
||||
|
||||
// PCS (pointing correction system) corrections
|
||||
mnt_coord_t pcsX, pcsY; // X - HA, Y - DEC for equatorial-type mount; X - AZ, Y - ZD for horizontal-type one
|
||||
|
||||
bool update(const std::chrono::system_clock::time_point& utc_time)
|
||||
{
|
||||
//
|
||||
|
||||
astro::mcc_julday(utc_time, mjd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool updateTime(const std::chrono::system_clock::time_point& utc_time)
|
||||
{
|
||||
// UTC to TAI
|
||||
double tai;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// implements a Finite State Machine Pattern
|
||||
template <MccMountType MOUNT_TYPE>
|
||||
|
||||
@ -19,6 +19,10 @@ template <typename T>
|
||||
concept mcc_scalar_or_simd_c = xsimd::is_batch<T>::value || std::is_arithmetic_v<T>;
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept mcc_real_scalar_or_real_range_c =
|
||||
std::floating_point<T> || std::ranges::output_range<T, float> || std::ranges::output_range<T, double>;
|
||||
|
||||
template <typename T>
|
||||
concept mcc_real_or_char_range =
|
||||
std::floating_point<T> ||
|
||||
@ -31,13 +35,17 @@ namespace mcc::astro
|
||||
{
|
||||
|
||||
// modified Julian date (based on ERFA eraCal2jd)
|
||||
// template <traits::mcc_scalar_or_simd_c T>
|
||||
template <traits::mcc_real_scalar_or_real_range_c ResT>
|
||||
static int mcc_julday(const std::chrono::system_clock::time_point& start_time,
|
||||
const std::chrono::system_clock::duration& step,
|
||||
std::vector<double, xsimd::default_allocator<double>>& mjd)
|
||||
ResT& mjd,
|
||||
const std::chrono::system_clock::duration& step = std::chrono::milliseconds(100))
|
||||
{
|
||||
if (mjd.empty()) {
|
||||
return -100;
|
||||
size_t mjd_size = 0;
|
||||
if constexpr (std::ranges::range<ResT>) {
|
||||
mjd_size = std::ranges::distance(mjd.begin(), mjd.end());
|
||||
if (!mjd_size) {
|
||||
return -100;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace std::literals::chrono_literals;
|
||||
@ -74,27 +82,52 @@ static int mcc_julday(const std::chrono::system_clock::time_point& start_time,
|
||||
|
||||
double mjd_float = static_cast<double>(mjd_int) +
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(start_time - dd).count() * nanosec;
|
||||
double d_step = std::chrono::duration_cast<std::chrono::nanoseconds>(step).count() * nanosec;
|
||||
|
||||
constexpr size_t reg_size = xsimd::batch<double>::size;
|
||||
size_t vec_size = mjd.size() - mjd.size() % reg_size;
|
||||
if constexpr (std::ranges::range<ResT>) {
|
||||
double d_step = std::chrono::duration_cast<std::chrono::nanoseconds>(step).count() * nanosec;
|
||||
|
||||
xsimd::batch<double> res_reg{mjd_float};
|
||||
xsimd::batch<double> step_reg = [d_step]<size_t... Is>(std::index_sequence<Is...>) {
|
||||
return xsimd::batch<double>{(Is * d_step)...};
|
||||
}(std::make_index_sequence<reg_size>{});
|
||||
size_t i = 0;
|
||||
|
||||
// vectorized part
|
||||
size_t i = 0;
|
||||
for (; i < vec_size; i += vec_size) {
|
||||
res_reg += step_reg;
|
||||
#ifdef VEC_XSIMD
|
||||
constexpr size_t reg_size = xsimd::batch<double>::size;
|
||||
size_t vec_size = mjd_size - mjd_size % reg_size;
|
||||
|
||||
res_reg.store_aligned(mjd.data() + i);
|
||||
}
|
||||
xsimd::batch<double> res_reg{mjd_float};
|
||||
xsimd::batch<double> step_reg = [d_step]<size_t... Is>(std::index_sequence<Is...>) {
|
||||
return xsimd::batch<double>{(Is * d_step)...};
|
||||
}(std::make_index_sequence<reg_size>{});
|
||||
|
||||
// scalar part
|
||||
for (size_t j = i; j < mjd.size(); ++j) {
|
||||
mjd[j] = mjd_float + j * d_step;
|
||||
alignas(xsimd::batch<double>::arch_type::alignment()) double arr[reg_size];
|
||||
|
||||
auto ptr = mjd.begin();
|
||||
|
||||
// vectorized part
|
||||
for (; i < vec_size; i += vec_size) {
|
||||
res_reg += step_reg;
|
||||
|
||||
if constexpr (std::ranges::contiguous_range<ResT>) {
|
||||
res_reg.store_unaligned(mjd.data() + i);
|
||||
// res_reg.store_aligned(mjd.data() + i);
|
||||
} else {
|
||||
res_reg.store_aligned(arr);
|
||||
std::ranges::copy(arr, ptr);
|
||||
|
||||
if constexpr (std::ranges::random_access_range<ResT>) {
|
||||
ptr += reg_size;
|
||||
} else {
|
||||
for (int k = 0; k < reg_size; ++k) {
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// scalar part
|
||||
for (size_t j = i; j < mjd_size; ++j, ++ptr) {
|
||||
*ptr = mjd_float + j * d_step;
|
||||
}
|
||||
} else { // result is scalar
|
||||
mjd = mjd_float;
|
||||
}
|
||||
|
||||
|
||||
@ -174,7 +207,29 @@ struct leapsecond_db_elem_t {
|
||||
double tai_utc; // TAI-UTC in seconds
|
||||
};
|
||||
|
||||
typedef std::vector<leapsecond_db_elem_t> leapsecond_db_t;
|
||||
// typedef std::vector<leapsecond_db_elem_t> leapsecond_db_t;
|
||||
|
||||
struct leapsecond_db_t {
|
||||
std::chrono::system_clock::time_point expireDate;
|
||||
std::vector<leapsecond_db_elem_t> db;
|
||||
};
|
||||
|
||||
|
||||
// init to some known state
|
||||
static leapsecond_db_t CURRENT_LEAPSECONDS_DB;
|
||||
// = {
|
||||
// {41317.0, 1, 1, 1972, 10}, {41499.0, 1, 7, 1972, 11}, {41683.0, 1, 1, 1973, 12},
|
||||
// {42048.0, 1, 1, 1974, 13}, {42413.0, 1, 1, 1975, 14}, {42778.0, 1, 1, 1976, 15},
|
||||
// {43144.0, 1, 1, 1977, 16}, {43509.0, 1, 1, 1978, 17}, {43874.0, 1, 1, 1979, 18},
|
||||
// {44239.0, 1, 1, 1980, 19}, {44786.0, 1, 7, 1981, 20}, {45151.0, 1, 7, 1982, 21},
|
||||
// {45516.0, 1, 7, 1983, 22}, {46247.0, 1, 7, 1985, 23}, {47161.0, 1, 1, 1988, 24},
|
||||
// {47892.0, 1, 1, 1990, 25}, {48257.0, 1, 1, 1991, 26}, {48804.0, 1, 7, 1992, 27},
|
||||
// {49169.0, 1, 7, 1993, 28}, {49534.0, 1, 7, 1994, 29}, {50083.0, 1, 1, 1996, 30},
|
||||
// {50630.0, 1, 7, 1997, 31}, {51179.0, 1, 1, 1999, 32}, {53736.0, 1, 1, 2006, 33},
|
||||
// {54832.0, 1, 1, 2009, 34}, {56109.0, 1, 7, 2012, 35}, {57204.0, 1, 7, 2015, 36},
|
||||
// {57754.0, 1, 1, 2017, 37}
|
||||
|
||||
// };
|
||||
|
||||
|
||||
struct earth_orient_db_elem_t {
|
||||
@ -186,27 +241,11 @@ struct earth_orient_db_elem_t {
|
||||
};
|
||||
|
||||
|
||||
// typedef std::vector<earth_orient_db_elem_t> earth_orient_db_t;
|
||||
struct earth_orient_db_t {
|
||||
std::chrono::system_clock::time_point bulletinDate{};
|
||||
std::vector<earth_orient_db_elem_t> db{};
|
||||
};
|
||||
|
||||
// init to some known state
|
||||
static leapsecond_db_t CURRENT_LEAPSECONDS_DB = {
|
||||
{41317.0, 1, 1, 1972, 10}, {41499.0, 1, 7, 1972, 11}, {41683.0, 1, 1, 1973, 12},
|
||||
{42048.0, 1, 1, 1974, 13}, {42413.0, 1, 1, 1975, 14}, {42778.0, 1, 1, 1976, 15},
|
||||
{43144.0, 1, 1, 1977, 16}, {43509.0, 1, 1, 1978, 17}, {43874.0, 1, 1, 1979, 18},
|
||||
{44239.0, 1, 1, 1980, 19}, {44786.0, 1, 7, 1981, 20}, {45151.0, 1, 7, 1982, 21},
|
||||
{45516.0, 1, 7, 1983, 22}, {46247.0, 1, 7, 1985, 23}, {47161.0, 1, 1, 1988, 24},
|
||||
{47892.0, 1, 1, 1990, 25}, {48257.0, 1, 1, 1991, 26}, {48804.0, 1, 7, 1992, 27},
|
||||
{49169.0, 1, 7, 1993, 28}, {49534.0, 1, 7, 1994, 29}, {50083.0, 1, 1, 1996, 30},
|
||||
{50630.0, 1, 7, 1997, 31}, {51179.0, 1, 1, 1999, 32}, {53736.0, 1, 1, 2006, 33},
|
||||
{54832.0, 1, 1, 2009, 34}, {56109.0, 1, 7, 2012, 35}, {57204.0, 1, 7, 2015, 36},
|
||||
{57754.0, 1, 1, 2017, 37}
|
||||
|
||||
};
|
||||
|
||||
|
||||
static earth_orient_db_t CURRENT_EARTH_ORIENT_DB;
|
||||
|
||||
@ -300,13 +339,20 @@ static bool mcc_parse_leapsecs(std::derived_from<std::basic_istream<char>> auto&
|
||||
|
||||
|
||||
leapsecond_db_t db;
|
||||
// leapsecond_db_elem_t db_elem;
|
||||
|
||||
for (std::string line; std::getline(stream, line);) {
|
||||
auto sv = utils::trimSpaces(line, utils::TrimType::TRIM_LEFT);
|
||||
|
||||
if (sv.size()) {
|
||||
if (sv[0] == comment_sym) { // comment string
|
||||
if (std::regex_match(line, expr_date_rx)) {
|
||||
auto pos = line.find("on");
|
||||
sv = utils::trimSpaces(std::string_view{line.begin() + pos + 2, line.end()},
|
||||
utils::TrimType::TRIM_LEFT);
|
||||
is.str({sv.begin(), sv.end()});
|
||||
is >> std::chrono::parse("%d %B %Y", db.expireDate);
|
||||
is.clear();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
@ -314,14 +360,15 @@ static bool mcc_parse_leapsecs(std::derived_from<std::basic_istream<char>> auto&
|
||||
}
|
||||
|
||||
if (std::regex_match(line, data_rx)) {
|
||||
is.str(std::move(line));
|
||||
is.str(line);
|
||||
is >> mjd >> day >> month >> year >> tai_utc;
|
||||
db.emplace_back(mjd, day, month, year, tai_utc);
|
||||
db.db.emplace_back(mjd, day, month, year, tai_utc);
|
||||
is.clear();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (db.empty()) {
|
||||
if (db.db.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -89,7 +89,8 @@ int main(int argc, char* argv[])
|
||||
ecode = 1;
|
||||
} else {
|
||||
std::cout << "IERS leap seconds data:\n";
|
||||
for (auto& el : mcc::astro::CURRENT_LEAPSECONDS_DB) {
|
||||
std::cout << "Expire date: " << mcc::astro::CURRENT_LEAPSECONDS_DB.expireDate << "\n";
|
||||
for (auto& el : mcc::astro::CURRENT_LEAPSECONDS_DB.db) {
|
||||
std::cout << "MJD: " << el.mjd << "\tTAI-UTC = " << el.tai_utc << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user