1#include "device/motor/j6006.h"
4using namespace roboctrl;
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");
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;
30 if (!connected_)
throw std::logic_error(
"J6006 must connect before start");
39 target_speed_ = enabled_ && !fault_latched_ && !
offline() && status_ == 1 && std::isfinite(speed)
40 ? std::clamp(speed, -info_.max_speed, info_.max_speed) : 0.f;
47 fault_latched_ =
false;
56 auto last_special = std::chrono::steady_clock::time_point::min();
59 const auto now = std::chrono::steady_clock::now();
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);
68 previous_enabled_ = enabled_;
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);
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);
基于 Linux SocketCAN 的 CAN 总线封装。
awaitable< void > set_angle_speed(fp32 speed) override
awaitable< void > set(fp32 linear_speed) override
void set_enabled(bool enabled) override
std::span< const std::byte > byte_span
只读 byte span。
awaitable< void > wait_for(const duration &duration)
协程任务等待。
auto spawn(task_context::task_type &&task)
添加一个协程任务到全局任务上下文中执行。
asio::awaitable< T > awaitable
协程任务类型。
bool shutdown_requested()
查询全局任务上下文是否已经进入停机流程。
bool offline() const
判断设备是否离线