GKD.RoboCtrl
RoboMaster Linux 电控:异步 IO、设备驱动与机器人控制
载入中...
搜索中...
未找到
super_cap.cpp
1#include "device/super_cap.h"
2#include "device/super_cap_protocol.hpp"
3#include "io/can.h"
4
5using namespace roboctrl;
6using namespace roboctrl::device;
7
8bool super_cap::init(const info_type& info) {
9 if (!valid_configuration(info)) throw std::invalid_argument("invalid super capacitor configuration");
10 if (configured_) throw std::logic_error("super capacitor already configured");
11 info_ = info;
12 configured_ = true;
13 return true;
14}
15
16void super_cap::connect() {
17 if (!configured_) throw std::logic_error("super capacitor must initialize before connect");
18 if (connected_) return;
19 get<io::can>(info_.can_name).on_data(info_.receive_id, [this](io::byte_span data) {
20 const auto feedback = super_cap_protocol::decode(data);
21 if (!feedback) return;
22 chassis_power_ = feedback->chassis_power;
23 chassis_power_limit_ = feedback->power_limit;
24 energy_ = feedback->energy;
25 error_code_ = feedback->error;
26 ++sample_sequence_;
27 tick();
28 }, 8);
29 connected_ = true;
30}
31
32void super_cap::start() {
33 if (!connected_) throw std::logic_error("super capacitor must connect before start");
34 if (started_) return;
35 started_ = true;
36 roboctrl::spawn(task());
37}
38
39awaitable<void> super_cap::set(bool enabled, uint16_t power_limit) {
40 if (!configured_) throw std::logic_error("super capacitor is not configured");
41 requested_enabled_ = enabled && !async::shutdown_requested();
42 requested_power_limit_ = async::shutdown_requested() ? 0 : std::min(power_limit, info_.max_power_limit);
43 last_command_ = std::chrono::steady_clock::now();
44 co_return;
45}
46
47awaitable<void> super_cap::task() {
48 while (true) {
49 const bool fresh = std::chrono::steady_clock::now() - last_command_ <= info_.command_timeout;
50 const bool enabled = super_cap_protocol::output_enabled(requested_enabled_, fresh, !offline(), error_code_);
51 const auto data = super_cap_protocol::encode(enabled,
52 fresh ? requested_power_limit_ : 0, info_.buffer_target);
53 co_await get<io::can>(info_.can_name).send(info_.command_id, data);
54 co_await wait_for(info_.resend_time);
55 }
56}
57
58awaitable<void> super_cap::stop_output() {
59 if (!connected_) co_return;
60 co_await set(false, 0);
61 const auto zero = super_cap_protocol::encode(false, 0, info_.buffer_target);
62 co_await get<io::can>(info_.can_name).send(info_.command_id, zero);
63}
基于 Linux SocketCAN 的 CAN 总线封装。
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