GKD.RoboCtrl
RoboMaster Linux 电控:异步 IO、设备驱动与机器人控制
载入中...
搜索中...
未找到
j6006.cpp
1#include "device/motor/j6006.h"
2#include "io/can.h"
3
4using namespace roboctrl;
5using namespace roboctrl::device;
6
7j6006::j6006(const info_type& info)
8 : motor_base{info.offline_timeout, info.radius}, info_{info} {
9 if (!valid_configuration(info)) throw std::invalid_argument("invalid J6006 configuration");
10}
11
12void j6006::connect() {
13 if (connected_) return;
14 get<io::can>(info_.can_name).on_data(info_.master_id, [this](io::byte_span data) {
15 const auto feedback = motor_protocol::decode_j6006(data, info_.id, info_.feedback_range);
16 if (!feedback) return;
17 status_ = feedback->status;
18 if (status_ >= 8) fault_latched_ = true;
19 encoder_raw_ = feedback->position_raw;
20 angle_ = info_.direction * feedback->position_rad;
21 angle_speed_ = info_.direction * feedback->velocity_rad_s;
22 torque_ = info_.direction * feedback->torque_nm;
23 if (status_ != 1) target_speed_ = 0.f;
24 tick();
25 }, 8);
26 connected_ = true;
27}
28
29void j6006::start() {
30 if (!connected_) throw std::logic_error("J6006 must connect before start");
31 if (started_) return;
32 started_ = true;
33 roboctrl::spawn(task());
34}
35
36awaitable<void> j6006::set(fp32 speed) { co_await set_angle_speed(speed / radius_); }
37
39 target_speed_ = enabled_ && !fault_latched_ && !offline() && status_ == 1 && std::isfinite(speed)
40 ? std::clamp(speed, -info_.max_speed, info_.max_speed) : 0.f;
41 co_return;
42}
43
45 enabled_ = false;
46 target_speed_ = 0.f;
47 fault_latched_ = false;
48}
49
50void j6006::set_enabled(bool enabled) {
51 if (enabled && !async::shutdown_requested()) enabled_ = true;
52 else disable();
53}
54
55awaitable<void> j6006::task() {
56 auto last_special = std::chrono::steady_clock::time_point::min();
57 bool first = true;
58 while (true) {
59 const auto now = std::chrono::steady_clock::now();
60 // Retry the requested enable state, but never clear a reported fault.
61 const bool request_enable = enabled_ && !fault_latched_ && (status_ == 0 || status_ == 1 || status_ == 0xff);
62 const bool transition = enabled_ != previous_enabled_;
63 if (first || transition || now - last_special >= std::chrono::milliseconds{100}) {
64 const auto data = motor_protocol::encode_j6006_enabled(request_enable);
65 co_await get<io::can>(info_.can_name).send(0x200 + info_.id, data);
66 last_special = now;
67 first = false;
68 previous_enabled_ = enabled_;
69 }
70 if (offline()) target_speed_ = 0.f;
71 const auto data = motor_protocol::encode_j6006_velocity(info_.direction * command_speed());
72 co_await get<io::can>(info_.can_name).send(0x200 + info_.id, data);
73 co_await wait_for(info_.control_time);
74 }
75}
76
77awaitable<void> j6006::stop_output() {
78 disable();
79 const auto disabled = motor_protocol::encode_j6006_enabled(false);
80 const auto zero = motor_protocol::encode_j6006_velocity(0.f);
81 co_await get<io::can>(info_.can_name).send(0x200 + info_.id, disabled);
82 co_await get<io::can>(info_.can_name).send(0x200 + info_.id, zero);
83}
基于 Linux SocketCAN 的 CAN 总线封装。
awaitable< void > set_angle_speed(fp32 speed) override
Definition j6006.cpp:38
void disable() override
Definition j6006.cpp:44
awaitable< void > set(fp32 linear_speed) override
Definition j6006.cpp:36
void set_enabled(bool enabled) override
Definition j6006.cpp:50
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
float fp32
单精度浮点别名。
Definition utils.hpp:22