GKD.RoboCtrl
RoboMaster Linux 电控:异步 IO、设备驱动与机器人控制
载入中...
搜索中...
未找到
robot.cpp
1#include "ctrl/robot.h"
2#include "core/async.hpp"
3#include "ctrl/shoot.h"
4#include "device/controlpad.h"
5#include "device/motor/dji.h"
6
7#include <algorithm>
8
9using namespace roboctrl::ctrl;
10
11bool robot::init(const info_type& info) {
12 control_pad_key_ = info.control_pad_key;
13 enable_chassis_ = info.enable_chassis;
14 enable_gimbal_ = info.enable_gimbal;
15 enable_shoot_ = info.enable_shoot;
16 if (enable_chassis_ && !device::chassis_registry::init(info.chassis_type, info.chassis_info))
17 return false;
18 if (enable_gimbal_ && !device::gimbal_registry::init(info.gimbal_type, info.gimbal_info))
19 return false;
20 chassis_ = enable_chassis_ ? device::chassis_registry::current() : nullptr;
21 gimbal_ = enable_gimbal_ ? device::gimbal_registry::current() : nullptr;
22 if (enable_gimbal_ && info.secondary_gimbal_info) {
23 secondary_gimbal_ = device::gimbal_registry::create(info.gimbal_type, *info.secondary_gimbal_info);
24 if (!secondary_gimbal_) return false;
25 }
26 if (enable_gimbal_ && info.large_yaw_info) {
27 large_yaw_ = device::gimbal_registry::create(info.gimbal_type, *info.large_yaw_info);
28 if (!large_yaw_) return false;
29 }
30 if (enable_shoot_ && !roboctrl::init(info.shoot_info)) return false;
31 if (enable_shoot_ && info.secondary_shoot_info) {
32 secondary_shoot_ = std::make_unique<shoot>();
33 if (!secondary_shoot_->init(*info.secondary_shoot_info)) return false;
34 }
35 controlled_motors_.clear();
36 const auto bind_motor = [this](const std::string& key) {
37 auto* motor = &roboctrl::get<device::dji_motor>(key);
38 if (std::find(controlled_motors_.begin(), controlled_motors_.end(), motor) == controlled_motors_.end())
39 controlled_motors_.push_back(motor);
40 };
41 if (enable_chassis_) {
42 bind_motor(info.chassis_info.left_front_motor);
43 bind_motor(info.chassis_info.right_front_motor);
44 bind_motor(info.chassis_info.left_rear_motor);
45 bind_motor(info.chassis_info.right_rear_motor);
46 }
47 set_state(robot_state::NoForce);
48 for (auto* gimbal : {gimbal_, secondary_gimbal_, large_yaw_})
49 if (gimbal) gimbal->start();
50 if (enable_shoot_) roboctrl::get<shoot>().start();
51 if (secondary_shoot_) secondary_shoot_->start();
52 auto motion = info.motion_info;
53 motion.control_pad_key = control_pad_key_;
54 motion.enable_shoot = enable_shoot_;
55 if (!roboctrl::init(motion)) return false;
57 log_info("Robot initiated");
58 return true;
59}
60
61bool robot::gimbals_initialized() const {
62 return (!gimbal_ || gimbal_->initialized()) &&
63 (!secondary_gimbal_ || secondary_gimbal_->initialized()) &&
64 (!large_yaw_ || large_yaw_->initialized());
65}
66
67bool robot::gimbals_online() const {
68 return (!gimbal_ || gimbal_->online()) &&
69 (!secondary_gimbal_ || secondary_gimbal_->online()) &&
70 (!large_yaw_ || large_yaw_->online());
71}
72
74 if (state != robot_state::NoForce && roboctrl::async::shutdown_requested()) {
75 log_warn("Ignored request to leave NoForce during shutdown");
76 state = robot_state::NoForce;
77 }
78 state_ = state;
79 const bool gimbal_enabled = state != robot_state::NoForce;
80 const bool motion_enabled = gimbal_enabled && state != robot_state::FinishInit;
81 if (chassis_) chassis_->set_enabled(motion_enabled);
82 for (auto* gimbal : {gimbal_, secondary_gimbal_, large_yaw_}) {
83 if (!gimbal) continue;
84 gimbal->set_enabled(gimbal_enabled);
85 gimbal->set_recentering(state == robot_state::FinishInit);
86 }
87 for (auto* motor : controlled_motors_) motor->set_enabled(motion_enabled);
88 if (enable_shoot_) roboctrl::get<shoot>().set_enabled(motion_enabled);
89 if (secondary_shoot_) secondary_shoot_->set_enabled(motion_enabled);
90}
91
93 auto& control_pad = roboctrl::get<device::control_pad>(control_pad_key_);
94 while (true) {
95 if (state_ != robot_state::NoForce && control_pad.offline()) {
96 log_warn("Control pad offline; entering NoForce");
97 set_state(robot_state::NoForce);
98 }
99 co_await roboctrl::wait_for(10ms);
100 }
101}
异步任务上下文组件。
roboctrl::awaitable< void > task()
运行机器人级状态机任务。
Definition robot.cpp:92
bool init(const info_type &info)
创建具体底盘/云台并初始化控制子系统。
Definition robot.cpp:11
robot_state state() const
获取当前机器人状态。
Definition robot.h:79
device::gimbal_base * gimbal() noexcept
Definition robot.h:69
void set_state(robot_state state)
设置当前机器人状态并更新输出使能。
Definition robot.cpp:73
virtual void set_enabled(bool)=0
启用或禁用底盘输出。
static chassis_base * current()
获取当前已初始化的底盘。
Definition base.cpp:32
static bool init(std::string_view type, const std::any &info)
按类型名初始化当前底盘。
Definition base.cpp:47
virtual void set_enabled(bool)=0
启用或禁用云台输出。
virtual void set_recentering(bool)=0
static gimbal_base * current()
获取当前已初始化的云台。
Definition base.cpp:33
static gimbal_base * create(std::string_view type, const std::any &info)
按类型名创建并初始化云台。
Definition base.cpp:37
static bool init(std::string_view type, const std::any &info)
按类型名初始化当前云台。
Definition base.cpp:54
void log_warn(std::format_string< Args... > fmt, Args &&...args) const
输出warn日志
Definition logger.h:226
void log_info(std::format_string< Args... > fmt, Args &&...args) const
输出info日志
Definition logger.h:214
遥控器串口设备与稳定输入快照。
DJI 电机及分组抽象。
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
auto init(const info_type &info) -> bool
初始化多例实例或单例实例
Definition multiton.hpp:252
机器人级状态与子系统生命周期编排。
robot_state
机器人控制状态。
Definition robot.h:26
发射器和拨弹机构控制。
机器人初始化参数及启用的子系统。
Definition robot.h:39
std::string chassis_type
配置选择的具体底盘类;当前仅实现标准麦轮底盘。
Definition robot.h:49
std::string gimbal_type
配置选择的具体云台类;当前仅实现标准双轴 IMU 云台。
Definition robot.h:51