GKD.RoboCtrl
RoboMaster Linux 电控:异步 IO、设备驱动与机器人控制
载入中...
搜索中...
未找到
utils.hpp
浏览该文件的文档.
1
6#pragma once
7
8#include <concepts>
9#include <array>
10#include <cstdint>
11#include <cstring>
12#include <chrono>
13#include <cmath>
14#include <numbers>
15#include <type_traits>
16
17#include "utils/concepts.hpp"
18
19namespace roboctrl{
20
22using fp32 = float;
24using fp64 = double;
25
30template<typename T>
31constexpr T Pi = std::numbers::pi_v<T>;
32
34constexpr auto Pi_f = Pi<fp32>;
35
36
41template<typename T>
42 requires std::is_arithmetic_v<T>
43struct vector{
44 T x;
45 T y;
46
50 T norm() const{
51 return std::sqrt(x * x + y * y);
52 }
53
58 return *this / norm();
59 }
60};
61
62using vectori = vector<int>;
63using vectorf = vector<float>;
64
66template<typename T>
67vector<T> operator + (vector<T> a,vector<T> b){
68 return {a.x+b.x,a.y+b.y};
69
70}
71
73template<typename T>
74vector<T> operator - (vector<T> a,vector<T> b){
75 return {a.x-b.x,a.y-b.y};
76}
77
79template<typename T>
80vector<T> operator * (vector<T> a,T b){
81 return {a.x * b,a.y * b};
82}
83
85template<typename T>
86vector<T> operator / (vector<T> a,T b){
87 return {a.x / b,a.y / b};
88}
89
94namespace utils{
95
99constexpr inline fp32 rad_format(fp32 ang){
100 fp32 ans = fmodf(ang + Pi_f, Pi_f * 2.f);
101 return (ans < 0.f) ? ans + Pi_f : ans - Pi_f;
102}
103
107template<typename C>
109 requires(C c) {
110 { c.data() } -> std::convertible_to<const std::byte*>;
111 { c.size() } -> std::convertible_to<std::size_t>;
112 };
113
120template<package T, byte_container C>
121T from_bytes(const C& bytes) {
122 if (bytes.size() != sizeof(T)) {
123 throw std::invalid_argument("byte buffer size does not match destination type");
124 }
125 T t{};
126 std::memcpy(&t, bytes.data(), sizeof(T));
127 return t;
128}
129
130template<package T>
131auto to_bytes(const T& t) -> std::array<std::byte, sizeof(T)> {
132 std::array<std::byte, sizeof(T)> bytes{};
133 std::memcpy(bytes.data(), &t, sizeof(T));
134 return bytes;
135}
136
144template<package T, typename C>
145requires requires(C& c) {
146 { c.data() } -> std::convertible_to<std::byte*>;
147 { c.size() } -> std::convertible_to<std::size_t>;
148}
149void to_bytes(const T& t, C& container) {
150 if (container.size() < sizeof(T)) {
151 throw std::invalid_argument("byte buffer is smaller than source type");
152 }
153 std::memcpy(container.data(), &t, sizeof(T));
154}
158inline auto now() {
159 static const auto init_time = std::chrono::steady_clock::now();
160 return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - init_time);
161}
162
166inline constexpr uint16_t make_u16(uint16_t high, uint16_t low) noexcept {
167 return (static_cast<uint16_t>(high) << 8) | static_cast<uint16_t>(low);
168}
169
173inline constexpr int16_t make_i16(int16_t high, int16_t low) noexcept {
174 return (static_cast<int16_t>(high) << 8) | static_cast<int16_t>(low);
175}
176
180inline constexpr std::byte to_byte(std::integral auto v) noexcept{
181 return static_cast<std::byte>(v);
182}
183
184template<typename T>
185struct function_arg : function_arg<decltype(&std::remove_cvref_t<T>::operator())> {};
186
187template<typename Ret, typename Arg>
188struct function_arg<Ret(Arg)> { using type = Arg; };
189
190template<typename Ret, typename Arg>
191struct function_arg<Ret(*)(Arg)> : function_arg<Ret(Arg)> {};
192
193template<typename Ret, typename Arg>
194struct function_arg<Ret(Arg) noexcept> : function_arg<Ret(Arg)> {};
195
196template<typename Ret, typename Arg>
197struct function_arg<Ret(*)(Arg) noexcept> : function_arg<Ret(Arg)> {};
198
199template<typename Ret, typename Class, typename Arg>
200struct function_arg<Ret(Class::*)(Arg)> { using type = Arg; };
201
202template<typename Ret, typename Class, typename Arg>
203struct function_arg<Ret(Class::*)(Arg) const> { using type = Arg; };
204
205template<typename Ret, typename Class, typename Arg>
206struct function_arg<Ret(Class::*)(Arg) noexcept> : function_arg<Ret(Class::*)(Arg)> {};
207
208template<typename Ret, typename Class, typename Arg>
209struct function_arg<Ret(Class::*)(Arg) const noexcept> : function_arg<Ret(Class::*)(Arg) const> {};
210
211template<typename Fn>
212using function_arg_t = typename function_arg<std::remove_cvref_t<Fn>>::type;
213
214}
215}
描述具有 data() 与 size() 接口的字节容器。
Definition utils.hpp:108
公共Concept与元类型工具。
constexpr std::byte to_byte(std::integral auto v) noexcept
辅助将整数转换为 std::byte。
Definition utils.hpp:180
constexpr int16_t make_i16(int16_t high, int16_t low) noexcept
将高低字节组合成有符号 16 位整数。
Definition utils.hpp:173
T from_bytes(const C &bytes)
将字节容器内容反序列化为平凡类型。
Definition utils.hpp:121
constexpr uint16_t make_u16(uint16_t high, uint16_t low) noexcept
将高低字节组合成无符号 16 位整数。
Definition utils.hpp:166
auto now()
记录程序启动后的纳秒级时间戳。
Definition utils.hpp:158
constexpr fp32 rad_format(fp32 ang)
将角度限制到[-Pi,Pi]范围内
Definition utils.hpp:99
简单的二维向量类型。
Definition utils.hpp:43
T norm() const
获取向量欧氏范数。
Definition utils.hpp:50
vector normalized() const
获取该向量的单位化结果。
Definition utils.hpp:57
constexpr T Pi
常量 Pi 的模板实例。
Definition utils.hpp:31
double fp64
双精度浮点别名。
Definition utils.hpp:24
constexpr auto Pi_f
单精度浮点类型的 Pi 常量。
Definition utils.hpp:34
float fp32
单精度浮点别名。
Definition utils.hpp:22