GKD.RoboCtrl
RoboMaster Linux 电控:异步 IO、设备驱动与机器人控制
载入中...
搜索中...
未找到
m9025.cpp
1#include "device/motor/m9025.h"
2#include "io/can.h"
3
4using namespace roboctrl;
5using namespace roboctrl::device;
6
7m9025::m9025(const info_type& info)
8 : motor_base{info.offline_timeout, info.radius}, info_{info}, pid_{info.pid_params} {
9 if (!valid_configuration(info)) throw std::invalid_argument("invalid M9025 configuration or feedback scale");
10}
11
12void m9025::connect() {
13 if (connected_) return;
14 get<io::can>(info_.can_name).on_data(0x140 + info_.id, [this](io::byte_span data) {
15 const auto feedback = motor_protocol::decode_m9025(data);
16 if (!feedback) return;
17 angle_ = info_.direction * 2.f * Pi_f * feedback->encoder / info_.encoder_counts_per_turn;
18 angle_speed_ = info_.direction * feedback->speed_raw * info_.speed_rad_per_count;
19 torque_ = info_.direction * feedback->current_raw;
20 tick();
21 }, 8);
22 connected_ = true;
23}
24
25void m9025::start() {
26 if (!connected_) throw std::logic_error("M9025 must connect before start");
27 if (started_) return;
28 started_ = true;
29 roboctrl::spawn(task());
30}
31
32awaitable<void> m9025::set(fp32 speed) { co_await set_angle_speed(speed / radius_); }
33
35 if (direct_current_) pid_.clean();
36 direct_current_ = false;
37 pid_.set_target(enabled_ && std::isfinite(speed) ? speed : 0.f);
38 co_return;
39}
40
42 if (!direct_current_) pid_.clean();
43 direct_current_ = true;
44 current_ = enabled_ && !offline() && std::isfinite(command)
45 ? std::clamp(command, -max_current(), max_current()) : 0.f;
46 co_return;
47}
48
50 enabled_ = false;
51 current_ = 0.f;
52 pid_.clean();
53}
54
55void m9025::set_enabled(bool enabled) {
56 if (enabled && !async::shutdown_requested()) enabled_ = true;
57 else disable();
58}
59
60awaitable<void> m9025::task() {
61 while (true) {
62 if (!enabled_ || offline()) {
63 current_ = 0.f;
64 pid_.clean();
65 } else if (!direct_current_) {
66 pid_.update(angle_speed(), std::chrono::duration<fp32>(info_.control_time).count());
67 current_ = pid_.state();
68 }
69 const auto data = motor_protocol::encode_m9025_current(static_cast<int16_t>(info_.direction * current()));
70 co_await get<io::can>(info_.can_name).send(0x140 + info_.id, data);
71 co_await wait_for(info_.control_time);
72 }
73}
74
75awaitable<void> m9025::stop_output() {
76 disable();
77 const auto zero = motor_protocol::encode_m9025_current(0);
78 co_await get<io::can>(info_.can_name).send(0x140 + info_.id, zero);
79}
基于 Linux SocketCAN 的 CAN 总线封装。
awaitable< void > set_angle_speed(fp32 speed) override
Definition m9025.cpp:34
awaitable< void > set(fp32 speed) override
Definition m9025.cpp:32
void disable() override
Definition m9025.cpp:49
void set_enabled(bool enabled) override
Definition m9025.cpp:55
awaitable< void > set_current(fp32 command) override
Definition m9025.cpp:41
std::span< const std::byte > byte_span
只读 byte span。
Definition base.hpp:45
awaitable< void > wait_for(const duration &duration)
协程任务等待。
Definition async.hpp:262
auto spawn(task_context::task_type &&task)
添加一个协程任务到全局任务上下文中执行。
Definition async.hpp:191
asio::awaitable< T > awaitable
协程任务类型。
Definition async.hpp:46
bool shutdown_requested()
查询全局任务上下文是否已经进入停机流程。
Definition async.hpp:226
bool offline() const
判断设备是否离线
Definition base.hpp:56
fp32 angle_speed() const
获取电机角速度(单位为rad/s)
Definition base.hpp:74
void clean()
清空积分项、误差缓存与输出。
Definition pid.h:106
T state() const
获取最新的控制输出。
Definition pid.h:116
void set_target(T target)
设置期望目标。
Definition pid.h:54
void update(T current, T dt)
根据当前值和采样周期更新 PID 输出。
Definition pid.h:67
float fp32
单精度浮点别名。
Definition utils.hpp:22