halx_driver
読み取り中…
検索中…
一致する文字列を見つけられません
c6x0.hpp
[詳解]
1#pragma once
2
3#include <algorithm>
4#include <array>
5#include <cstddef>
6#include <cstdint>
7#include <optional>
8#include <utility>
9
10#include <halx/core.hpp>
11#include <halx/peripheral/can.hpp>
12
13namespace halx::driver {
14
15enum class C6x0Type {
18};
19
30
32public:
33 C6x0Manager(peripheral::CanBase &can) : can_{can} {
34 auto filter_index = can_.attach_rx_queue({0x200, 0x7F0, false}, rx_queue_);
35 if (!filter_index) {
36 std::terminate();
37 }
38 filter_index_ = *filter_index;
39 }
40
41 ~C6x0Manager() { can_.detach_rx_filter(filter_index_); }
42
43 void update() {
44 while (auto msg = rx_queue_.pop()) {
45 if (0x201 <= msg->id && msg->id < 0x201 + 8) {
46 Params &motor = params_[msg->id - 0x201];
47 int16_t position =
48 static_cast<int16_t>(msg->data[0] << 8 | msg->data[1]);
49 if (motor.prev_position_) {
50 int16_t delta = position - *motor.prev_position_;
51 if (delta > 4096) {
52 delta -= 8192;
53 } else if (delta < -4096) {
54 delta += 8192;
55 }
56 motor.position_ += delta;
57 } else {
58 motor.position_ = position;
59 }
60 motor.prev_position_ = position;
61 motor.rpm_ = static_cast<int16_t>(msg->data[2] << 8 | msg->data[3]);
62 motor.current_raw_ =
63 static_cast<int16_t>(msg->data[4] << 8 | msg->data[5]);
64 }
65 }
66 }
67
68 bool transmit() {
69 peripheral::CanMessage msg{};
70 msg.id = 0x200;
71 msg.ide = false;
72 msg.dlc = 8;
73 for (size_t i = 0; i < 4; ++i) {
74 msg.data[i * 2] = params_[i].current_ref_raw_ >> 8;
75 msg.data[i * 2 + 1] = params_[i].current_ref_raw_;
76 }
77 if (!can_.transmit(msg, 5)) {
78 return false;
79 }
80 msg.data.fill(0);
81 msg.id = 0x1FF;
82 for (size_t i = 0; i < 4; ++i) {
83 msg.data[i * 2] = params_[i + 4].current_ref_raw_ >> 8;
84 msg.data[i * 2 + 1] = params_[i + 4].current_ref_raw_;
85 }
86 return can_.transmit(msg, 5);
87 }
88
89 int64_t get_position(C6x0Id id) {
90 return params_[std::to_underlying(id)].position_;
91 }
92
93 int16_t get_rpm(C6x0Id id) { return params_[std::to_underlying(id)].rpm_; }
94
95 int16_t get_current_raw(C6x0Id id) {
96 return params_[std::to_underlying(id)].current_raw_;
97 }
98
99 void set_current_ref_raw(C6x0Id id, int16_t current) {
100 params_[std::to_underlying(id)].current_ref_raw_ = current;
101 }
102
103private:
104 struct Params {
105 int64_t position_ = 0;
106 std::optional<int16_t> prev_position_;
107 int16_t rpm_ = 0;
108 int16_t current_raw_ = 0;
109 int16_t current_ref_raw_ = 0;
110 };
111
112 peripheral::CanBase &can_;
113 core::RingBuffer<peripheral::CanMessage> rx_queue_{64};
114 size_t filter_index_;
115 std::array<Params, 8> params_{};
116};
117
118class C6x0 {
119public:
120 C6x0(C6x0Manager &manager, C6x0Type type, C6x0Id id)
121 : manager_{manager}, type_{type}, id_{id} {}
122
124
125 int64_t get_position() { return manager_.get_position(id_); }
126
127 int16_t get_rpm() { return manager_.get_rpm(id_); }
128
129 float get_current() {
130 switch (type_) {
131 case C6x0Type::C610:
132 return manager_.get_current_raw(id_);
133 case C6x0Type::C620:
134 return manager_.get_current_raw(id_) / 16384.0f * 20000.0f;
135 }
136 }
137
138 void set_current_ref(float current) {
139 switch (type_) {
140 case C6x0Type::C610:
141 manager_.set_current_ref_raw(id_,
142 std::clamp(current, -10000.0f, 10000.0f));
143 break;
144 case C6x0Type::C620:
145 manager_.set_current_ref_raw(
146 id_, std::clamp(current, -20000.0f, 20000.0f) / 20000.0f * 16384.0f);
147 break;
148 }
149 }
150
151private:
152 C6x0Manager &manager_;
153 C6x0Type type_;
154 C6x0Id id_;
155};
156
157} // namespace halx::driver
Definition c6x0.hpp:31
C6x0Manager(peripheral::CanBase &can)
Definition c6x0.hpp:33
void set_current_ref_raw(C6x0Id id, int16_t current)
Definition c6x0.hpp:99
int16_t get_rpm(C6x0Id id)
Definition c6x0.hpp:93
void update()
Definition c6x0.hpp:43
bool transmit()
Definition c6x0.hpp:68
int16_t get_current_raw(C6x0Id id)
Definition c6x0.hpp:95
int64_t get_position(C6x0Id id)
Definition c6x0.hpp:89
~C6x0Manager()
Definition c6x0.hpp:41
int64_t get_position()
Definition c6x0.hpp:125
void set_current_ref(float current)
Definition c6x0.hpp:138
float get_current()
Definition c6x0.hpp:129
int16_t get_rpm()
Definition c6x0.hpp:127
C6x0(C6x0Manager &manager, C6x0Type type, C6x0Id id)
Definition c6x0.hpp:120
~C6x0()
Definition c6x0.hpp:123
Definition amt21.hpp:10
C6x0Id
Definition c6x0.hpp:20
@ ID_2
Definition c6x0.hpp:22
@ ID_4
Definition c6x0.hpp:24
@ ID_5
Definition c6x0.hpp:25
@ ID_1
Definition c6x0.hpp:21
@ ID_6
Definition c6x0.hpp:26
@ ID_7
Definition c6x0.hpp:27
@ ID_8
Definition c6x0.hpp:28
@ ID_3
Definition c6x0.hpp:23
C6x0Type
Definition c6x0.hpp:15
@ C610
Definition c6x0.hpp:16
@ C620
Definition c6x0.hpp:17