UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
RoboMasterMotor.hpp
[詳解]
1//
2// ロボマスモーター
3//
4// Copyright (c) 2022-2024 udonrobo
5//
6
7#pragma once
8
9#include <Udon/Com/Can.hpp>
11
12namespace Udon
13{
14
15 namespace Impl
16 {
17
21 {
22 public:
27 RoboMasterBase(Udon::ICanBus& bus, uint8_t motorId, bool direction = true)
28 : bus{ bus }
29 , motorId{ motorId }
30 , direction{ direction }
31 , nodeRx{ bus.createRx(static_cast<uint32_t>(0x200 + Constrain((int)motorId, 1, 8)), 8) }
32 {
33 if (motorId > 4)
34 nodeTx = bus.createTx(static_cast<uint32_t>(0x1FF), 8);
35 else
36 nodeTx = bus.createTx(static_cast<uint32_t>(0x200), 8);
37
38 nodeRx->onReceive = onReceive;
39 nodeRx->param = this;
40 }
41
42
46
47
50 : bus{ other.bus }
51 , motorId{ other.motorId }
52 , direction{ other.direction }
53 , nodeTx{ other.nodeTx }
54 , nodeRx{ other.nodeRx }
55 {
56 nodeRx->param = this; // ここでotherに登録されていたthisポインタを上書きするため、コピーすることができない
57 }
58
59
63 double getAngle() const
64 {
65 return (angle + offsetAngle) * 2 * Udon::Pi / ppr * directionSign();
66 }
67
68
72 double getRawAngle() const
73 {
74 return angle * 2 * Udon::Pi / ppr * directionSign();
75 }
76
77
80 int16_t getVelocity() const
81 {
82 const auto velocity = (nodeRx->data[2] << 8 | nodeRx->data[3]) * directionSign();
83 return static_cast<int16_t>(velocity);
84 }
85
86
89 int16_t getTorqueCurrent() const
90 {
91 const int current = (nodeRx->data[4] << 8 | nodeRx->data[5]) * directionSign();
92 return static_cast<int16_t>(current);
93 }
94
95
98 uint8_t getTemperature() const
99 {
100 return nodeRx->data[6];
101 }
102
103 protected:
106 void setCurrent(int16_t current)
107 {
108 current = current * directionSign();
109
110 const auto transmitCurrent = static_cast<int16_t>(current * 16384 / 20000); // 16bit符号なし整数に変換
111
112 if (motorId > 4)
113 {
114 const auto motorIndex = (motorId - 4 - 1) * 2;
115 nodeTx->data[motorIndex + 0] = transmitCurrent >> 8 & 0xff; // high byte
116 nodeTx->data[motorIndex + 1] = transmitCurrent >> 0 & 0xff; // low byte
117 }
118 else
119 {
120 const auto motorIndex = (motorId - 1) * 2;
121 nodeTx->data[motorIndex + 0] = transmitCurrent >> 8 & 0xff; // high byte
122 nodeTx->data[motorIndex + 1] = transmitCurrent >> 0 & 0xff; // low byte
123 }
124 }
125
126 private:
128 Udon::ICanBus& bus;
129
131 uint8_t motorId;
132
134 bool direction;
135
137 Udon::CanTxNode* nodeTx;
138
139
141 Udon::CanRxNode* nodeRx;
142
143
145 int64_t offsetAngle = 0;
146 int64_t angle = 0;
147
148
150 static constexpr int32_t ppr = 8192;
151
152 int16_t directionSign() const
153 {
154 return direction ? 1 : -1;
155 }
156
157 static void onReceive(void* p)
158 {
159 auto self = static_cast<RoboMasterBase*>(p);
160
161 // 変化角を計算
162 const auto currentAngle = self->nodeRx->data[0] << 8 | self->nodeRx->data[1];
163 const auto dTheta = self->angle - currentAngle;
164 self->angle = currentAngle;
165
166 // 変化量がいきなり半周を超えた -> 計算値が-π~π間を通過 -> 一周分オフセットを加減算
167 if (dTheta > ppr / 2)
168 {
169 self->offsetAngle += ppr;
170 }
171 else if (dTheta < -ppr / 2)
172 {
173 self->offsetAngle -= ppr;
174 }
175 }
176 };
177
178 } // namespace Impl
179
180
184 : public Impl::RoboMasterBase
185 {
186 public:
191 using RoboMasterBase::RoboMasterBase;
192
194 static constexpr int16_t CurrentMin = -10000;
195
197 static constexpr int16_t CurrentMax = 10000;
198
201 void setCurrent(int16_t current)
202 {
203 RoboMasterBase::setCurrent(Constrain(current, CurrentMin, CurrentMax));
204 }
205 };
206
207
211 : public Impl::RoboMasterBase
212 {
213 public:
218 using RoboMasterBase::RoboMasterBase;
219
221 static constexpr int16_t CurrentMin = -20000;
222
224 static constexpr int16_t CurrentMax = 20000;
225
228 void setCurrent(int16_t current)
229 {
230 RoboMasterBase::setCurrent(Constrain(current, CurrentMin, CurrentMax));
231 }
232 };
233} // namespace Udon
CANバス管理クラス インターフェース
Definition ICanBus.hpp:49
virtual CanTxNode * createTx(uint32_t id, size_t length)=0
送信ノードを作成
RoboMaster 基底クラス
Definition RoboMasterMotor.hpp:21
int16_t getTorqueCurrent() const
モーターのトルク電流を取得
Definition RoboMasterMotor.hpp:89
int16_t getVelocity() const
モーターの速度を取得
Definition RoboMasterMotor.hpp:80
double getAngle() const
モーターの角度を取得
Definition RoboMasterMotor.hpp:63
RoboMasterBase(const RoboMasterBase &)=delete
コピーコンストラクタ
RoboMasterBase(RoboMasterBase &&other)
ムーブコンストラクタ
Definition RoboMasterMotor.hpp:49
double getRawAngle() const
モーターの角度を取得
Definition RoboMasterMotor.hpp:72
RoboMasterBase(Udon::ICanBus &bus, uint8_t motorId, bool direction=true)
コンストラクタ
Definition RoboMasterMotor.hpp:27
void setCurrent(int16_t current)
モーターの電流を設定
Definition RoboMasterMotor.hpp:106
uint8_t getTemperature() const
モーターの温度を取得
Definition RoboMasterMotor.hpp:98
RoboMasterC610クラス
Definition RoboMasterMotor.hpp:185
void setCurrent(int16_t current)
モーターの電流を設定
Definition RoboMasterMotor.hpp:201
static constexpr int16_t CurrentMin
指定可能電流最小値
Definition RoboMasterMotor.hpp:194
static constexpr int16_t CurrentMax
指定可能電流最大値
Definition RoboMasterMotor.hpp:197
RoboMasterC620クラス
Definition RoboMasterMotor.hpp:212
void setCurrent(int16_t current)
モーターの電流を設定
Definition RoboMasterMotor.hpp:228
static constexpr int16_t CurrentMin
指定可能電流最小値
Definition RoboMasterMotor.hpp:221
static constexpr int16_t CurrentMax
指定可能電流最大値
Definition RoboMasterMotor.hpp:224
Definition Bit.hpp:12
constexpr double Pi
π
Definition Math.hpp:26
constexpr A Constrain(const A &amt, const B &low, const C &high)
値を指定された範囲内に収める (std::clamp)
Definition Math.hpp:68
CAN受信ノード
Definition ICanBus.hpp:28
std::vector< uint8_t > data
Definition ICanBus.hpp:31
void * param
Definition ICanBus.hpp:34
void(* onReceive)(void *)
Definition ICanBus.hpp:33
CAN送信ノード
Definition ICanBus.hpp:17
std::vector< uint8_t > data
Definition ICanBus.hpp:20