114 lines
3.1 KiB
C++
114 lines
3.1 KiB
C++
#pragma once
|
|
|
|
/* MOUNT CONTROL COMPONENTS LIBRARY */
|
|
|
|
/* MOUNT HARDWARE CONCEPTS */
|
|
|
|
|
|
#include <utility>
|
|
#include "mcc_traits.h"
|
|
|
|
namespace mcc
|
|
{
|
|
|
|
namespace traits
|
|
{
|
|
|
|
// encoder basic concept (e.g. mount axis encoder or motor shaft one)
|
|
template <typename T>
|
|
concept mcc_hw_encoder_c = requires(T t, const T t_const) {
|
|
typename T::error_t;
|
|
|
|
typename T::time_point_t;
|
|
typename T::coord_t;
|
|
typename T::speed_t;
|
|
typename T::accel_t;
|
|
// typename T::high_order_deriv_t;
|
|
|
|
requires requires(typename T::state_t st) {
|
|
std::same_as<decltype(st.time), typename T::time_point_t>;
|
|
std::same_as<decltype(st.pos), typename T::coord_t>;
|
|
std::same_as<decltype(st.speed), typename T::speed_t>;
|
|
std::same_as<decltype(st.accel), typename T::accel_t>;
|
|
// std::same_as<decltype(st.high_order), typename T::high_order_deriv_t>;
|
|
};
|
|
|
|
{ t_const.id() } -> mcc_formattable;
|
|
|
|
{ t.getState(std::declval<typename T::state_t&>()) } -> std::same_as<typename T::error_t>;
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
concept mcc_hw_motor_c = requires(T t, const T t_const) {
|
|
typename T::coord_t;
|
|
typename T::speed_t;
|
|
typename T::accel_t;
|
|
|
|
requires requires(typename T::pos_t st) {
|
|
std::same_as<decltype(st.pos), typename T::coord_t>;
|
|
std::same_as<decltype(st.speed), typename T::speed_t>; // means maximal allowed speed
|
|
std::same_as<decltype(st.accel), typename T::accel_t>; // means a maximal allowed acceleration (jerk)
|
|
};
|
|
|
|
|
|
{ t_const.id() } -> mcc_formattable;
|
|
|
|
{ t.rotate(std::declval<typename T::pos_t>()) } -> std::same_as<typename T::error_t>;
|
|
|
|
{ t.stop() } -> std::same_as<typename T::error_t>;
|
|
};
|
|
|
|
|
|
|
|
namespace details
|
|
{
|
|
template <typename T>
|
|
concept mcc_tuple_enc_ref_c = mcc_tuple_c<T> && requires(T t) {
|
|
[]<template <typename...> typename TT, mcc_hw_encoder_c... Ts>(TT<Ts & ...>) {}(t);
|
|
};
|
|
|
|
template <typename T>
|
|
concept mcc_tuple_enc_cref_c = mcc_tuple_c<T> && requires(T t) {
|
|
[]<template <typename...> typename TT, mcc_hw_encoder_c... Ts>(TT<const Ts & ...>) {}(t);
|
|
};
|
|
|
|
template <typename T>
|
|
concept mcc_tuple_motor_ref_c = mcc_tuple_c<T> && requires(T t) {
|
|
[]<template <typename...> typename TT, mcc_hw_motor_c... Ts>(TT<Ts & ...>) {}(t);
|
|
};
|
|
|
|
|
|
template <typename T>
|
|
concept mcc_hw_enc_lref_c = std::is_lvalue_reference_v<T> && mcc_hw_encoder_c<std::remove_cvref_t<T>>;
|
|
|
|
|
|
template <typename T>
|
|
concept mcc_hw_motor_lref_c = std::is_lvalue_reference_v<T> && mcc_hw_motor_c<std::remove_cvref_t<T>>;
|
|
|
|
} // namespace details
|
|
|
|
|
|
// a very generic mount hardware concept
|
|
template <typename T>
|
|
concept mcc_mount_hardware_c = requires(T t, const T t_const) {
|
|
{ t_const.id() } -> mcc_formattable;
|
|
|
|
// access to encoders
|
|
{ t_const.encoders() } -> details::mcc_tuple_enc_cref_c;
|
|
{ t.encoders() } -> details::mcc_tuple_enc_ref_c;
|
|
|
|
{ t.encoderPosX() } -> details::mcc_hw_enc_lref_c;
|
|
{ t.encoderPosY() } -> details::mcc_hw_enc_lref_c;
|
|
|
|
// access to motors
|
|
{ t.motors() } -> details::mcc_tuple_motor_ref_c;
|
|
|
|
{ t.motorX() } -> details::mcc_hw_motor_lref_c;
|
|
{ t.motorY() } -> details::mcc_hw_motor_lref_c;
|
|
};
|
|
|
|
} // namespace traits
|
|
|
|
} // namespace mcc
|