UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
RoboMasterMotor.hpp
[詳解]
1//
2// ロボマスモーター
3//
4// Copyright (c) 2022 udonrobo
5//
6
7#pragma once
8
9#include <Udon/Com/Can.hpp>
11#include <Udon/Types/Range.hpp>
13
14namespace Udon
15{
19 {
20 public:
26 : bus{ bus }
27 , motorId{ motorId }
28 , direction{ direction }
29 {
30 // 送信者インスタンスを作成 id = 0x1FF(id1~4) or 0x200(id5~8)
31 // createTx 関数はすでに存在する場合、存在するインスタンスを返す。そのため複数のロボマスインスタンスで同じ送信者インスタンスを共有できる。
32 if (motorId > 4)
33 nodeTx = bus.createTx(static_cast<uint32_t>(0x1FF), 8);
34 else
35 nodeTx = bus.createTx(static_cast<uint32_t>(0x200), 8);
36
37 // 受信者インスタンスを作成 id = 0x200 + id
38 const uint32_t rxId = static_cast<uint32_t>(0x200 + Constrain(motorId, 1, 8));
39 nodeRx = bus.createRx(rxId, 8);
40 nodeRx->onReceive = onReceive;
41 nodeRx->param = this;
42 }
43
44
48
49
52 : bus{ other.bus }
53 , motorId{ other.motorId }
54 , direction{ other.direction }
55 , nodeTx{ other.nodeTx }
56 , nodeRx{ other.nodeRx }
57 {
58 nodeRx->param = this; // ここでotherに登録されていたthisポインタを上書きするため、コピーすることができない
59 }
60
61
65 double getAngle() const
66 {
67 return (angle + offsetAngle) * 2 * Udon::Pi / ppr * Udon::DirectionToSign(direction);
68 }
69
70
74 double getRawAngle() const
75 {
76 return angle * 2 * Udon::Pi / ppr * Udon::DirectionToSign(direction);
77 }
78
79
82 int16_t getVelocity() const
83 {
84 const auto velocity = (nodeRx->data[2] << 8 | nodeRx->data[3]) * Udon::DirectionToSign(direction);
85 return static_cast<int16_t>(velocity);
86 }
87
88
91 int16_t getTorqueCurrent() const
92 {
93 const int current = (nodeRx->data[4] << 8 | nodeRx->data[5]) * Udon::DirectionToSign(direction);
94 return static_cast<int16_t>(current);
95 }
96
97
100 uint8_t getTemperature() const
101 {
102 return nodeRx->data[6];
103 }
104
107 virtual void setCurrent(int16_t current) = 0;
108
112
113 protected:
114 void setRawCurrent(int16_t rawCurrent)
115 {
116 const auto transmitCurrent = static_cast<int16_t>(rawCurrent * Udon::DirectionToSign(direction) * 16384 / 20000);
117
118 if (motorId > 4)
119 {
120 const auto motorIndex = (motorId - 4 - 1) * 2;
121 nodeTx->data[motorIndex + 0] = transmitCurrent >> 8 & 0xff; // high byte
122 nodeTx->data[motorIndex + 1] = transmitCurrent >> 0 & 0xff; // low byte
123 }
124 else
125 {
126 const auto motorIndex = (motorId - 1) * 2;
127 nodeTx->data[motorIndex + 0] = transmitCurrent >> 8 & 0xff; // high byte
128 nodeTx->data[motorIndex + 1] = transmitCurrent >> 0 & 0xff; // low byte
129 }
130 }
131
132 private:
134 Udon::ICanBus& bus;
135
137 int motorId;
138
140 Udon::Direction direction;
141
143 Udon::CanTxNode* nodeTx;
144
145
147 Udon::CanRxNode* nodeRx;
148
149
151 int64_t offsetAngle = 0;
152 int64_t angle = 0;
153
154
156 static constexpr int32_t ppr = 8192;
157
158 static void onReceive(void* p)
159 {
160 auto self = static_cast<RoboMasterBase*>(p);
161
162 // 変化角を計算
163 const auto currentAngle = self->nodeRx->data[0] << 8 | self->nodeRx->data[1];
164 const auto dTheta = self->angle - currentAngle;
165 self->angle = currentAngle;
166
167 // 変化量がいきなり半周を超えた -> 計算値が-π~π間を通過 -> 一周分オフセットを加減算
168 if (dTheta > ppr / 2)
169 {
170 self->offsetAngle += ppr;
171 }
172 else if (dTheta < -ppr / 2)
173 {
174 self->offsetAngle -= ppr;
175 }
176 }
177 };
178
182 : public RoboMasterBase
183 {
184 public:
190
193 {
194 return { -10000, 10000 };
195 }
196
199 void setCurrent(int16_t current) override
200 {
202 }
203 };
204
205
209 : public RoboMasterBase
210 {
211 public:
217
220 {
221 return { -20000, 20000 };
222 }
223
226 void setCurrent(int16_t current) override
227 {
229 }
230 };
231} // namespace Udon
CANバス管理クラス インターフェース
Definition ICanBus.hpp:49
RoboMaster 基底クラス
Definition RoboMasterMotor.hpp:19
double getRawAngle() const
モーターの角度を取得
Definition RoboMasterMotor.hpp:74
void setRawCurrent(int16_t rawCurrent)
Definition RoboMasterMotor.hpp:114
virtual void setCurrent(int16_t current)=0
モーターの電流を設定
RoboMasterBase(const RoboMasterBase &)=delete
コピーコンストラクタ
double getAngle() const
モーターの角度を取得
Definition RoboMasterMotor.hpp:65
RoboMasterBase(Udon::ICanBus &bus, int motorId, Udon::Direction direction=Udon::Direction::Forward)
コンストラクタ
Definition RoboMasterMotor.hpp:25
int16_t getTorqueCurrent() const
モーターのトルク電流を取得
Definition RoboMasterMotor.hpp:91
int16_t getVelocity() const
モーターの速度を取得
Definition RoboMasterMotor.hpp:82
uint8_t getTemperature() const
モーターの温度を取得
Definition RoboMasterMotor.hpp:100
RoboMasterBase(RoboMasterBase &&other)
ムーブコンストラクタ
Definition RoboMasterMotor.hpp:51
virtual Udon::Range< int16_t > getCurrentRange() const =0
指定可能電流範囲
RoboMasterC610クラス
Definition RoboMasterMotor.hpp:183
void setCurrent(int16_t current) override
モーターの電流を設定
Definition RoboMasterMotor.hpp:199
RoboMasterBase(Udon::ICanBus &bus, int motorId, Udon::Direction direction=Udon::Direction::Forward)
コンストラクタ
Definition RoboMasterMotor.hpp:25
Udon::Range< int16_t > getCurrentRange() const override
指定可能電流範囲
Definition RoboMasterMotor.hpp:192
RoboMasterC620クラス
Definition RoboMasterMotor.hpp:210
void setCurrent(int16_t current) override
モーターの電流を設定
Definition RoboMasterMotor.hpp:226
Udon::Range< int16_t > getCurrentRange() const override
指定可能電流範囲
Definition RoboMasterMotor.hpp:219
RoboMasterBase(Udon::ICanBus &bus, int motorId, Udon::Direction direction=Udon::Direction::Forward)
コンストラクタ
Definition RoboMasterMotor.hpp:25
Definition Bit.hpp:12
constexpr double Pi
π
Definition Math.hpp:27
int DirectionToSign(Direction direction)
Definition Direction.hpp:14
Direction
方向
Definition Direction.hpp:9
@ Forward
Definition Direction.hpp:10
constexpr A Constrain(const A &amt, const B &low, const C &high)
値を指定された範囲内に収める (std::clamp)
Definition Math.hpp:69
CanBusTeensy< Bus > * CanBusTeensy< Bus >::self
Definition CanBusTeensy.hpp:275
CAN受信ノード
Definition ICanBus.hpp:28
CAN送信ノード
Definition ICanBus.hpp:17
範囲を表す型
Definition Range.hpp:8