添加了部分说明文档

This commit is contained in:
NeoZng
2022-12-19 17:15:42 +08:00
parent cb1856a6dd
commit 22171177da
7 changed files with 91 additions and 7 deletions

View File

@@ -1,3 +1,59 @@
# application
这是application层的说明
<p align='right'>neozng1@hnu.edu.cn</p>
这是application层的说明。
## 使用说明
在main函数中包含`robot.h`头文件,这是对整车的抽象。将`INStask``motortask``ledtask``monitortask`这四个task加入`freertos.c`中,创建对应的任务,设置合适的任务运行间隔;然后将`robottask`放入freertos.c中同样以一定的频率运行。 在初始化实时系统之前,在`main()`中调用`RobotInit()`进行整车的初始化。
INStask的运行频率为1kHzmotortask推荐的运行频率为200Hz\~500Hz对于高实时性要求的电机可以提升到1kHz不过要注意CAN总线的负载。ledtask的运行频率推荐为1kHzmonitortask的运行频率推荐为50\~100Hzrobottask的运行频率推荐为150Hz以上应当高于视觉发送的频率若后续使用插帧应该保证不低过motortask太多。
若使用双板,则在`robot_def.h`中给对应的开发板设定宏定义,如底盘板使用`#define CHASSIS_BOARD`,云台板使用`#define GIMBAL_BOARD`;单个开发板控制整车,则定义`#define ONE_BOARD`。在每个应用中都已经使用编译预处理指令完成条件编译会自动根据设定的宏切换功能。使用双板的时候目前板间通信通过CAN完成因此两个开发板会挂载在一条总线上在两个开发板对这条总线的其他使用CAN的设备进行配置时注意**不要发生ID冲突**,还要注意**防止负载过大**。
**同样,在该文件中你需要修改一些关于机器人的参数**。比如底盘和云台对齐时yaw电机编码器的值拨盘的单圈载弹量、底盘的轴距等等。
## 封装总览
Robot.c是整个机器人的抽象其下有4个应用robot_cmdgimbalchassisshoot。此框架当前是针对步兵/英雄/哨兵设计的其他机器人只需要根据各自的特殊机构进行修改即可。robot_cmd是整个机器人的核心应用其负责接受遥控器/上位机发来的指令并将指令转化为实际的运动控制目标发送给其他三个应用。后者会根据robot_cmd发来的命令设定电机和其他执行单元的参考值等。
为了进一步解耦应用之间的关系,这里并没有采用层级结构(或设计模式中所谓的**工厂模式**即robot_cmd包含其他三个模块而采用了应用并列的**发布-订阅**机制四个应用之间没有任何相互包含关系他们之间的通信通过module层提供的`message_center`实现。每个应用会通过该模块向一些话题事件发布一些消息同时从一些话题订阅消息。如robot_cmd应用会发布其他三个模块的控制信息同时订阅其他三个模块的反馈信息。其他三个模块会订阅robot_cmd发布的控制信息同时发布反馈给robot_cmd的信息他们不需要知道彼此的存在只是从`message_center`处获取其他应用发布的消息或向自己发布的话题推送消息。
## 整车程序流程
```mermaid
graph TD
main调用RobotInit进行初始化 --> RobotInit调用基础bsp初始化以及各个app的初始化 --> 各个app进行消息订阅初始化和自有模块的初始化 --> 启动实时系统 --> 各任务开始运行
```
任务开始之后每个app之间的交互关系如下
```mermaid
graph TD
robot_cmd获取遥控器/上位机指令以及各个应用发布的回传信息 --> 将指令转化为具体的控制信息 --> 发布指令到对应话题
```
gimbal/chassis/shoot则根据订阅的robot_cmd发布的消息将具体的控制信息根据当前模式转化为执行单元的目标值通过自己拥有的模块完成这些指令然后把回传的信息发布到对应话题。
每个应用的具体流程和实现,参见它们各自的说明文档。
## 开发要点
各个应用之间务必通过`message_center`以发布-订阅的方式进行消息交换,不要出现包含关系,这可以大大减小耦合度并提高合作开发的效率。

View File

@@ -176,11 +176,11 @@ static void EmergencyHandler()
}
}
void GimbalCMDTask()
void RobotCMDTask()
{
// 从其他应用获取回传数据
#ifdef ONE_BOARD
SubGetMessage(chassis_feed_sub, (void*)&chassis_fetch_data);
SubGetMessage(chassis_feed_sub, (void *)&chassis_fetch_data);
#endif // ONE_BOARD
#ifdef GIMBAL_BOARD
chassis_fetch_data = *(Chassis_Upload_Data_s *)CANCommGet(cmd_can_comm);

View File

@@ -3,6 +3,6 @@
void GimbalCMDInit();
void GimbalCMDTask();
void RobotCMDTask();
#endif // !GIMBAL_CMD_H

View File

@@ -0,0 +1,28 @@
# robot_cmd
<p align='right'>neozng1@hnu.edu.cn</p>
## 运行流程
运行流程可以很直观的从`RobotCMDTask()`中看出。首先通过消息订阅机制,获取其他应用的反馈信息,然后使用`CalcOffsetAngle()`计算底盘和云台的offset angle使得底盘始终获知当前的正方向接着根据当前是通过键鼠or遥控器控制调用对应的函数将控制指令量化为具体的控制信息得到控制信息之后先不急着发布而是检测重要的模块和应用是否掉线或出现异常以及遥控器是否进入紧急停止模式如果以上情况发生那么将所有的控制信息都置零即让电机和其他执行单元保持静止。最后还是通过pubsub机制把具体的控制信息发布到对应话题让其他应用获取。
## 外部接口
## 私有函数和变量

View File

@@ -29,7 +29,7 @@ void RobotInit()
void RobotTask()
{
#if defined(ONE_BOARD) || defined(GIMBAL_BOARD)
GimbalCMDTask();
RobotCMDTask();
GimbalTask();
ShootTask();
#endif