1#include "device/motor/m9025.h"
4using namespace roboctrl;
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");
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;
26 if (!connected_)
throw std::logic_error(
"M9025 must connect before start");
35 if (direct_current_) pid_.
clean();
36 direct_current_ =
false;
37 pid_.
set_target(enabled_ && std::isfinite(speed) ? speed : 0.f);
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;
65 }
else if (!direct_current_) {
66 pid_.
update(
angle_speed(), std::chrono::duration<fp32>(info_.control_time).count());
67 current_ = pid_.
state();
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);
77 const auto zero = motor_protocol::encode_m9025_current(0);
78 co_await get<io::can>(info_.can_name).send(0x140 + info_.id, zero);
基于 Linux SocketCAN 的 CAN 总线封装。
awaitable< void > set_angle_speed(fp32 speed) override
awaitable< void > set(fp32 speed) override
void set_enabled(bool enabled) override
awaitable< void > set_current(fp32 command) 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
判断设备是否离线
fp32 angle_speed() const
获取电机角速度(单位为rad/s)
void clean()
清空积分项、误差缓存与输出。
T state() const
获取最新的控制输出。
void set_target(T target)
设置期望目标。
void update(T current, T dt)
根据当前值和采样周期更新 PID 输出。