UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
Position.hpp
[詳解]
1//
2// ロボットの位置 (座標、旋回角) を表す型
3//
4// Copyright (c) 2022-2024 udonrobo
5//
6
7#pragma once
8
10#include <algorithm>
11#include <array>
12
13#include "Polar.hpp"
14#include "Vector2D.hpp"
15
19
20namespace Udon
21{
22
25 struct Pos
26 {
27
29 using ValueType = double;
30
33
36
38 constexpr Pos() noexcept
39 : vector()
40 , turn()
41 {
42 }
43
45 constexpr Pos(const Pos& rhs) noexcept
46 : vector(rhs.vector)
47 , turn(rhs.turn)
48 {
49 }
50
52 constexpr Pos(const Udon::Vec2& vector, ValueType turn) noexcept
53 : vector(vector)
54 , turn(turn)
55 {
56 }
57
59 Pos& operator=(const Pos&) = default;
60
64 constexpr Pos operator+(const Pos& rhs) const noexcept { return { vector + rhs.vector, turn + rhs.turn }; }
65 constexpr Pos operator-(const Pos& rhs) const noexcept { return { vector - rhs.vector, turn - rhs.turn }; }
66 constexpr Pos operator*(const Pos& rhs) const noexcept { return { vector * rhs.vector, turn * rhs.turn }; }
67 constexpr Pos operator/(const Pos& rhs) const noexcept { return { vector / rhs.vector, turn / rhs.turn }; }
68 constexpr Pos operator+(ValueType rhs) const noexcept { return { vector + rhs, turn + rhs }; }
69 constexpr Pos operator-(ValueType rhs) const noexcept { return { vector - rhs, turn - rhs }; }
70 constexpr Pos operator*(ValueType rhs) const noexcept { return { vector * rhs, turn * rhs }; }
71 constexpr Pos operator/(ValueType rhs) const noexcept { return { vector / rhs, turn / rhs }; }
72
76 Pos operator+=(const Pos& rhs) noexcept { return *this = *this + rhs; }
77 Pos operator-=(const Pos& rhs) noexcept { return *this = *this - rhs; }
78 Pos operator*=(const Pos& rhs) noexcept { return *this = *this * rhs; }
79 Pos operator/=(const Pos& rhs) noexcept { return *this = *this / rhs; }
80 Pos operator+=(ValueType rhs) noexcept { return *this = *this + rhs; }
81 Pos operator-=(ValueType rhs) noexcept { return *this = *this - rhs; }
82 Pos operator*=(ValueType rhs) noexcept { return *this = *this * rhs; }
83 Pos operator/=(ValueType rhs) noexcept { return *this = *this / rhs; }
84
88 constexpr bool operator==(const Pos& rhs) const noexcept { return vector == rhs.vector && turn == rhs.turn; }
89
93 constexpr bool operator!=(const Pos& rhs) const noexcept { return !(*this == rhs); }
94
96 constexpr explicit operator bool() const noexcept
97 {
98 return vector || turn;
99 }
100
102 constexpr bool isZero() const noexcept
103 {
104 return !Pos::operator bool();
105 }
106
108 void clear() noexcept
109 {
110 *this = {};
111 }
112
116 {
117 return {
118 vector.abs(),
120 };
121 }
122
123 Pos mapped(double inMin, double inMax, double outMin, double outMax) const noexcept
124 {
125 return {
126 vector.mapped(inMin, inMax, outMin, outMax),
127 Map(turn, inMin, inMax, outMin, outMax),
128 };
129 }
130
131 Pos updateVector(const Udon::Vec2& v) const noexcept
132 {
133 return { v, turn };
134 }
135
136 template <typename Visitor>
137 Pos modifyVector(Visitor&& visitor) const noexcept
138 {
139 return { visitor(vector), turn };
140 }
141
142 Pos updateTurn(double t) const noexcept
143 {
144 return { vector, t };
145 }
146
147 template <typename Visitor>
148 Pos modifyTurn(Visitor&& visitor) const noexcept
149 {
150 return { vector, visitor(turn) };
151 }
152
153 // template <size_t WheelCount>
154 // std::array<double, WheelCount> toOmni() const
155 // {
156 // static_assert(WheelCount >= 3, "WheelCount must be greater than or equal to 3.");
157 // static_assert(WheelCount == 4, "Not supported over 4 wheels now.");
158 // }
159
160 template <size_t N>
161 std::array<double, N> toOmni() const
162 {
163 uint8_t powerLimit = 255;
164 uint8_t turnPowerLimit = 255;
165 const auto mappedTurn = Udon::Map(turn, -255, 255, -turnPowerLimit, turnPowerLimit);
166
167 std::array<double, 4> powers{ {
168 +vector.x + -vector.y + mappedTurn,
169 -vector.x + -vector.y + mappedTurn,
170 -vector.x + +vector.y + mappedTurn,
171 +vector.x + +vector.y + mappedTurn,
172 } };
173
174 // 上で算出した出力値は {powerLimit} を超える場合があります。
175 // 超えた場合、最大出力のモジュールの出力を {powerLimit} として他のモジュールの出力を圧縮します。
176 auto&& max = Udon::Abs(*std::max_element(powers.begin(), powers.end(), [](double lhs, double rhs)
177 { return Udon::Abs(lhs) < Udon::Abs(rhs); }));
178
179 if (max > powerLimit)
180 {
181 const auto ratio = powerLimit / max;
182
183 std::transform(powers.begin(), powers.end(), powers.begin(),
184 [ratio](double power)
185 { return power * ratio; });
186 }
187
188 // todo
189 return powers;
190 }
191
203 template <size_t WheelCount = 4>
204 std::array<Udon::Polar, WheelCount> toSteer(uint8_t powerLimit = 255,
205 uint8_t turnPowerLimit = 255) const
206 {
207 static_assert(WheelCount >= 3, "WheelCount must be greater than or equal to 3.");
208 static_assert(WheelCount == 4, "Not supported over 4 wheels now."); // todo: 5輪以上対応
209
210 // 旋回移動ベクトル
211 const Udon::Vec2 turnVec = { 0, Udon::Map(this->turn, -255, 255, -turnPowerLimit, turnPowerLimit) };
212
213 // 旋回移動ベクトル、進行移動ベクトルから角車輪の進行方向ベクトルを算出
214 std::array<Udon::Vec2, WheelCount> vectors;
215
216 for (size_t i = 0; i < WheelCount; ++i)
217 {
218 vectors.at(i) = vector + turnVec.rotated(Udon::Pi * (i * 2 + 3) / WheelCount);
219 }
220
221 // 方向ベクトルから極座標系(theta:旋回角, r:タイヤ出力)に変換
222 std::array<Udon::Polar, WheelCount> modules;
223
224 for (size_t i = 0; i < WheelCount; ++i)
225 {
226 modules.at(i) = vectors.at(i).toPolar();
227 }
228
229 // 上で算出した出力値は {limit} を超える場合があります。
230 // 超えた場合、最大出力のモジュールの出力を {limit} として他のモジュールの出力を圧縮します。
231 // 出力値はベクトルの長さから求めるため負にならない {max} は正の値であることが保証
232 auto&& max = *std::max_element(modules.begin(), modules.end(), [](const Udon::Polar& lhs, const Udon::Polar& rhs)
233 { return lhs.r < rhs.r; });
234
235 if (max.r > powerLimit)
236 {
237 const auto ratio = powerLimit / max.r;
238 for (auto&& module : modules)
239 {
240 module.r *= ratio;
241 }
242 }
243
244 return modules;
245 }
246
247#ifdef ARDUINO
249 void show() const
250 {
251 vector.show();
252 Serial.print(F("turn: ")), Serial.print(turn), Serial.print('\t');
253 }
254#endif
255
257 };
258
259 using Stick = Pos;
260
261} // namespace Udon
#define F(x)
Definition Show.hpp:17
Definition Bit.hpp:12
constexpr T Abs(const T &rhs)
絶対値を返す (std::abs)
Definition Math.hpp:98
constexpr double Pi
π
Definition Math.hpp:26
constexpr double Map(const double value, const double inputMin, const double inputMax, const double outputMin, const double outputMax)
数値をある範囲から別の範囲に再マッピングする
Definition Math.hpp:136
極座標系
Definition Polar.hpp:21
ロボットの位置
Definition Position.hpp:26
constexpr Pos operator+(ValueType rhs) const noexcept
Definition Position.hpp:68
Pos modifyVector(Visitor &&visitor) const noexcept
Definition Position.hpp:137
constexpr Pos(const Pos &rhs) noexcept
デフォルトコピーコンストラクタ
Definition Position.hpp:45
Pos updateVector(const Udon::Vec2 &v) const noexcept
Definition Position.hpp:131
std::array< double, N > toOmni() const
Definition Position.hpp:161
Pos operator/=(ValueType rhs) noexcept
Definition Position.hpp:83
constexpr Pos operator/(const Pos &rhs) const noexcept
Definition Position.hpp:67
Pos operator-=(const Pos &rhs) noexcept
Definition Position.hpp:77
Pos mapped(double inMin, double inMax, double outMin, double outMax) const noexcept
Definition Position.hpp:123
constexpr Pos operator/(ValueType rhs) const noexcept
Definition Position.hpp:71
Pos operator/=(const Pos &rhs) noexcept
Definition Position.hpp:79
constexpr Pos operator-(const Pos &rhs) const noexcept
Definition Position.hpp:65
void clear() noexcept
値クリア
Definition Position.hpp:108
constexpr Pos operator+(const Pos &rhs) const noexcept
算術演算子
Definition Position.hpp:64
Pos abs()
絶対値を取る
Definition Position.hpp:115
double ValueType
要素の型
Definition Position.hpp:29
constexpr bool isZero() const noexcept
要素がすべて0であるかを変えす
Definition Position.hpp:102
Pos operator+=(ValueType rhs) noexcept
Definition Position.hpp:80
Pos updateTurn(double t) const noexcept
Definition Position.hpp:142
Pos operator-=(ValueType rhs) noexcept
Definition Position.hpp:81
Pos operator*=(ValueType rhs) noexcept
Definition Position.hpp:82
constexpr Pos operator*(ValueType rhs) const noexcept
Definition Position.hpp:70
UDON_ENUMERABLE(vector, turn)
constexpr Pos(const Udon::Vec2 &vector, ValueType turn) noexcept
コンストラクタ
Definition Position.hpp:52
Pos operator+=(const Pos &rhs) noexcept
複合代入演算子
Definition Position.hpp:76
Pos & operator=(const Pos &)=default
デフォルトコピー代入演算子
constexpr bool operator!=(const Pos &rhs) const noexcept
比較演算子
Definition Position.hpp:93
constexpr Pos operator-(ValueType rhs) const noexcept
Definition Position.hpp:69
ValueType turn
旋回角 [rad]
Definition Position.hpp:35
Udon::Vec2 vector
座標
Definition Position.hpp:32
Pos operator*=(const Pos &rhs) noexcept
Definition Position.hpp:78
Pos modifyTurn(Visitor &&visitor) const noexcept
Definition Position.hpp:148
std::array< Udon::Polar, WheelCount > toSteer(uint8_t powerLimit=255, uint8_t turnPowerLimit=255) const
独立ステアリング機構のタイヤ出力値、旋回角を取得する
Definition Position.hpp:204
constexpr Pos() noexcept
デフォルトコンストラクタ
Definition Position.hpp:38
constexpr Pos operator*(const Pos &rhs) const noexcept
Definition Position.hpp:66
constexpr bool operator==(const Pos &rhs) const noexcept
比較演算子
Definition Position.hpp:88
二次元ベクトル
Definition Vector2D.hpp:22
ValueType y
Y成分
Definition Vector2D.hpp:31
constexpr Vec2 mapped(ValueType fromMin, ValueType fromMax, ValueType toMin, ValueType toMax) const noexcept
各要素をある範囲から別の範囲に再マップしたベクトルを返す
Definition Vector2D.hpp:254
Vec2 rotated(ValueType angle) const noexcept
原点を中心に回転したベクトルを返す
Definition Vector2D.hpp:172
ValueType x
X成分
Definition Vector2D.hpp:28
Vec2 abs() const noexcept
絶対値を取る
Definition Vector2D.hpp:140