# 2022控制组方向线上测试 **Repository Path**: buaarobot_admin/ControlGroupOnlineTest2022 ## Basic Information - **Project Name**: 2022控制组方向线上测试 - **Description**: 北航机器人队2022控制组方向线上测试题发布 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 1 - **Created**: 2022-07-16 - **Last Updated**: 2025-05-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 2022控制组单片机方向线上测试 ## 第一周测试题 ### 1.git基本操作 #### 任务简介 > Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目,可以帮助你进行自动的版本管理。控制组单片机端**之后的线上测试都是通过`gitee`发布**,在多人协作的情况下,使用`git`就会相当的方便,能够有效地协调多位开发者对不同地方的改动。 #### 任务要求 - 安装git,并且注册好`gitee`账户与`git`绑定,并且点击[**邀请链接**]([2022控制组线上测试题 (gitee.com)](https://gitee.com/buaarobot_admin/ControlGroupOnlineTest2022/invite_link?invite=7600632b845df338c29945b4076b0cacf366c75cc061dd04b7993663152babc5b5bb6a8590dff59e5f318cd36bbddc3a))加入本远程仓库 - 注意邀请链接的有效期为3天 - 在想要克隆本仓库的地方,右键菜单点击“**`Git Bash Here`**”,输入以下代码,即可实现将远程仓库克隆到本地的操作,注意**之后的任务会放置在任务文件夹中** ```c >>> git clone https://gitee.com/buaarobot_admin/ControlGroupOnlineTest2022.git ``` - 创建一个markdown文件,命名格式为{**{你的名字}.md**},如`李明.md` 撰写你对本周题目的难度的看法,创建一个简述自己对**git组成以及常见命令使用原理的理解**的markdown文件,命名格式为 **{你的名字ToMarkDown}.md** 。 两个文件统一放到`ControlGroupSCMOnlineTest2022/第一周测试题/task1`下面 - `git commit -m {改动的内容}` 在这里写清这次提交改动的内容:**{你的名字}提交task1** - 本任务结果提交方式为**git提交** ##### 提示信息 - 可以使用`git push` 将本地所有未上传的提交推送到远程仓库 - 此时有可能会提示推送失败,这是因为远程仓库里面有本地未获取的提交 - 此时需要先`git pull`获取当前远程仓库的最新版本, 将远程仓库的最新版本和本地最新版本合并(`merge`)后,才能够推送 - 第一次进行提交操作时需要登记提交者信息,提交时`git`会有相关的操作说明 - 更多详细的`git`用法请查询参考资料或借助网络搜索 ##### 注意 **不是**所有任务都需要利用git进行提交,第一周以及以后的其它任务提交方式**请以对应的任务说明为准** #### 参考资料 - [git入门教程](https://www.cnblogs.com/imyalost/p/8762522.html) - [菜鸟教程yyds](https://www.runoob.com/git/git-tutorial.html) - 一个可以打开md文件的软件:[Typora](https://www.typora.io/windows/dev_release.html) ### 2.PID控制程序编写及封装 #### 任务简介 - PID算法是控制领域应用最广泛的算法,其计算流程与其应用场景并无关系,为了避免重复编写同样的代码,我们往往会将PID算法进行封装,初始化过后直接调用即可。 #### 任务说明 - 1.请完善`PID.c`中的两个空白函数,函数的功能已经在注释中写出。 `void PID_StructInit(void PID_StructInit(PID_t *pid, float p, float i, float d, float integral_limit, float max_output))` `static void Calculate(PID_t *pid, float current_value, float target_value)` - 2.请根据自己编写好的函数进行对`PID.c`的封装。 需要达到的要求是用户在定义 `PID_t` 结构体后(例如 `PID_t TestPID`),先运行`PID_StructInit`函数,再使用`TestPID.f_Calculate(&TestPID, Current_value, Target_value)`即可完成计算,计算的结果保存在结构体中。 - 3.通过查阅关于`PID`的资料,说一说P、I、D分别有什么作用,如果让你调节PID参数,你会如何开始调节。写成一个TXT文档,字数不超过100字,以自己的名字命名即可。 - 4.本任务的代码均放在 `第一周测试题/task2`文件夹下。 #### 任务要求 - 需要提交的文件:`PID.c`和`PID.h`和`PID参数说明文档`。将这些文件放在`第一周任务/task2`目录下即可。 - 程序有一定可读性,包含适当的注释;**即使没能完成任务,也请提交上来**,并且在同目录下创建一个README文本文件中写明原因以及完成的进度情况。 - 本任务提交方式为**邮箱提交**,地址为`bhjqrdkzz2022@163.com`(与其他需要邮箱提交的任务放在**同一个zip文件**中,zip文件命名格式为 **{你的名字}第一周测试题.zip)** #### 参考资料 - [初识PID-搞懂PID概念](https://zhuanlan.zhihu.com/p/74131690) ### 3. 串口的使用 #### 任务要求 - 任务实现过程为:串口调试助手**通过串口**发送字符'a'(char类型数据,不用数据帧编码),下位机开始通过相同串口循环打印数字1-10(**Simple帧编码**),发送字符'b'(char类型数据,不用数据帧编码),下位机开始通过相同串口循环打印数字11-20(**Normal帧编码**),发送字符'c'(char类型数据,不用数据帧编码),下位机开始通过相同串口循环打印数字21-30(**Trigger帧编码**) - **要求** - 与下位机STM32F407之间的通信使用给定的三种数据帧(由操作手**在串口助手上**进行指定) - **仅需要**编写**下位机**程序 - 将编写好的KEIL工程文件放在task3文件夹下与其他任务的文件一起打包为zip文件,命名为"**{你的名字}+控制组测试题第一周**"发送至指定邮箱bhjqrdkzz2022@163.com #### 任务提示 - 三种数据帧示意图如下所示 - 参数说明 - 帧头:0x7E(type: uint8_t) - 类型位:Simple:0,Normal:1,Trigger:2(type: uint8_t) - Simple: - 长度位:5(type: uint8_t) - 编号位:简单帧ID(type: uint8_t) - 数据位: - size:4 - type:float(4字节) - Normal - 长度位:sizeof(“buaarobotteam”)+4 - 名称位:(char[])(“buaarobotteam”) - 数据位: - size:4 - type:float(4字节) - Trigger - 长度位:{数量位}*4+2(type: uint8_t) - 编号位:ID位(type: uint8_t) - 数量位:uint8_t - 参数位: - size:{数量位}*4 - type:float(4字节) - 校验位:0x03(type: uint8_t) - 帧尾:0x04(type: uint8_t) 例:Simple帧数字1:7E0005010000803F0304 - 对于三种数据帧的ID位可均设置为1. - 数据帧编码采用**小端模式**,STM32采用的是**小端模式** **参考资料** - [经典永流传](https://gitee.com/link?target=https%3A%2F%2Fwww.bilibili.com%2Fvideo%2FBV1kx411k7JT) - [知识宝库](https://gitee.com/link?target=https%3A%2F%2Fspace.bilibili.com%2F394620890) ### 4.串口调试助手 #### 任务要求 - 利用Qt实现能够按数据帧格式编码数据的串口调试助手 - **要求** - 需要实现串口调试助手的基本功能,如选择串口,设置波特率、停止位等(注:此处的校验位、停止位等视为不影响数据帧的编码,可任意实现) - 除正常串口调试的基本功能外,要对发送的数据(单个或多个float类型数据,取决于数据帧类型)进行编码,编码数据帧格式按任务3所述 - **仅需要**编写**串口调试助手**程序 - 将编写好的Qt工程文件放在task4文件夹下与其他任务的文件一起打包为zip文件,命名为"**{你的名字}+控制组测试题第一周**"发送至指定邮箱bhjqrdkzz2022@163.com ## 第二周测试题 ### 5.CAN通信 #### 任务说明 - 子任务1:查阅相关资料,简述CAN通信相比于其他有线通信方式的优点。试从物理层和协议层,谈谈自己对CAN通信“简便、可靠”的理解。写成一个txt文档,字数不超过200字,以自己名字命名即可。 - 子任务2:阅读参考资料“RM C610无刷电机调速器使用说明 发布版”中的“CAN通信协议”内容,任选一款含有CAN的STM32芯片,新建Keil工程尝试编写程序,利用STM32控制板与C610电调进行通信,并利用“第一周测试题”中封装好的“PID控制程序”控制1个C610电调及电机工作在固定速度。具体提示如下: 1. 阅读参考资料“RM C610无刷电机调速器使用说明 发布版”中的“电调反馈报文格式”内容,配置CAN过滤器,接收C610电调(认为帧ID为1)向总线上发送的反馈信息。 2. 接收到C610电调反馈的信息,提取数据域中的“转子转速”内容,作为输入项输入到封装好的“PID控制程序”中,并将“PID控制程序”的输出作为控制电流,准备向CAN总线上发送。 3. 阅读参考资料“RM C610无刷电机调速器使用说明 发布版”中“电调接收报文格式”,配置CAN发送格式,将2中控制电流发送给电调。 #### 任务要求 - 与C610电调通信的波特率为1Mbps。 - 将以上内容放在task5文件夹下与其他任务的文件一起打包为zip文件地址为zip文件命名格式为**{你的名字}第二周测试题.zip**),提交到邮箱`bhjqrdkzz2022@163.com` #### 参考资料 [RM C610无刷电机调速器使用说明 发布版](https://rm-static.djicdn.com/tem/RM%20C610%E6%97%A0%E5%88%B7%E7%94%B5%E6%9C%BA%E8%B0%83%E9%80%9F%E5%99%A8%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%20%E5%8F%91%E5%B8%83%E7%89%88.pdf) [正点原子STM32开发板 — 正点原子资料下载中心 1.0.0 文档](http://47.111.11.73/docs/boards/stm32/index.html) ### 6. 无刷电机控制 #### 任务简介 ##### 无刷直流电机 - 机器人的驱动通常有电动、气动和液动三种,电机驱动是三种方式中功率密度最大、功能方式最简、伺服精度最高的控制方式。在移动式机器人中,常用直流电源(如航模电池)给电机供电,实现机器人的能源-驱动系统。 - 电动机一般分为同步电机和异步电机,其共同点是都需要旋转的磁场来产生驱动力。为了产生旋转的磁场,就需要交变的电流。因此,直流电机控制的核心技术是将直流电压逆变为交流电压,进而产生交变电流。逆变技术有很多种,最简单的是通过电刷换向,应用此技术的电机称为有刷直流电机(BDC: Brush Direct Current Motor)。直流有刷电机的优点为驱动电路简单、工作稳定、力矩大。其缺点为能量转换效率低、需要维护更换电刷、转速一般较低。 - 相应的,使用电子管换向而取代电刷换向的电机,称为无刷直流电机(BLDC: Brushless Direct Current Motor)。随着无刷电机控制技术的发展,更多的半导体公司推出了成熟的无刷电机控制方案。而由于无刷电机能量密度高、无需维护、效率高、伺服精度高的优点,移动机器人中使用无刷电机成为主流趋势。传统的BLDC控制方法是通过霍尔传感器以及换向电子管,因此其通过生产时对磁隙的调制,使反电动势为方波。而由于控制方法的精进,使得我们不仅可以用直流电源驱动BLDC,还可以直接使用直流电源驱动一些交流电机,比如永磁同步电机(PMSM: Permanent-Magnet Synchronous Motor),对其控制方法称为空间矢量控制(FOC: Field-Oriented Control)。 - 在北航机器人队中,我们通常使用PMSM作为机器人驱动器。 ##### 电机编码器 - 电机位置的传感对电机控制与机器人控制都有重要意义,编码器是常用的电机位置传感器。常见的编码器的种类有光电编码器和磁编码器等,按照反馈信息形式,又分为增量式编码器与绝对式编码器。 #### 任务说明 1. 以下为北航机器人队常用的M3508电机,请根据下图,查阅资料,简述机器人驱动电机的3个主要组成部分,并分别简述其作用,不超过200字。 M3508 2. 请通过查阅资料,简述BLDC与PMSM的区别,并简述PMSM的控制原理,不超过300字。 3. 无刷电机的控制方式常见为三环控制,即电流环、速度环和位置环通过级联的方式实现控制。常见的FOC控制器或电调通常会封装电流环,机器人队使用的控制器带有三环的封装,其中电流环参数会通过测量电机绕组的电阻和电感参数自动计算,而速度环和位置环参数与外部负载有关。请简述三环分别的输入量与输出量的物理意义,以及三环控制的作用,不超过100字。 #### 任务要求 - 将简述内容整理在"无刷电机控制.md"文件中,放在`/task4`目录下。 - 若未及时完成任务,也请一并提交;若对题目理解有困难,可在微信群讨论。 - 将以上内容放在task6文件夹下与其他任务的文件一起打包为zip文件地址为zip文件命名格式为**{你的名字}第二周测试题.zip**),提交到邮箱`bhjqrdkzz2022@163.com` #### 参考资料 - [【自制FOC驱动器】深入浅出讲解FOC算法与SVPWM技术](https://zhuanlan.zhihu.com/p/147659820) - [一文了解BLDC与PMSM的区别](https://blog.csdn.net/sphinz1/article/details/109265584) ### 7.全场定位基础 #### 任务简介: 全场定位模块是整个机器人中必不可少的一部分,通过陀螺仪、[正交轮](https://www.mfcad.com/tuzhi/1658/1082371.html)与激光,机器人可以知晓自己在场地中的位置,从而更好地完成一系列自动任务,底盘正交轮1,2和世界坐标系如下图所示。 #### 任务说明: - 子任务1:推导依靠正交轮与陀螺仪实现全场定位的基本方法。已知正交轮的基本结构如上图所示,假定每个轮子顺时针转动为正,假定陀螺仪的欧拉角已经得到,并且偏航角顺时针为正。 - 子任务2:在Location.c与Location.h中,根据注释提示补全代码,实现定位信息的获取。 - 子任务3:请简要叙述陀螺仪、光纤陀螺、激光陀螺的区别与联系,不超过500字 - 将以上内容放在task7文件夹下与其他任务的文件一起打包为zip文件地址为zip文件命名格式为**{你的名字}第二周测试题.zip**),提交到邮箱`bhjqrdkzz2022@163.com` #### 参考资料 - 王志君. 移动机器人全场定位系统的研究[D].电子科技大学,2015. ## 第三周测试题 ### 8.PI校正 #### 任务简介 根据控制模型,得出最优的PI控制参数 #### 任务说明 FOC三环控制模型中,为减小控制量,获得稳定的控制量,将电机A、B、C三相静止坐标系通过Park变换和Clack变换后得到随定子旋转的d-q坐标系,得到电机电压电压与电流关系如下式所示,其中 $u_d,u_q$ 为定子电压d-q轴分量, $i_d,i_q$为定子电流d-q轴分量,$L_d,L_q$为定子电感d-q轴分量,$\omega_e$为电机电角速度(rad/s),$\phi_s$为电机永磁体磁链(Wb)。 $$ \begin{align} u_{q}=&R_{s} \times i_{q}+L_{q} \frac{d i_{q}}{d t}+\omega_{e}( \phi_s+L_{d} i_{d}) \\ u_d=&R_s \times i_{d}+L_d \frac{d i_d}{d t}-\omega_e L_q i_q \end{align} $$ 可以看出上式中电流电压是耦合的,在电机转速较低时$\omega_e$近似为0(高速时通过对电机参数辨识,实现前馈解耦),对于表贴式电机(SPM)$L_d=L_q=L$,上式可简化为 $$ \begin{align}u_{q}=&R_{{s}} \times i_{q}+L \frac{d i_{q}}{d t}\\ u_d=&R_s \times i_{d}+L\frac{d i_{d}}{d t}\end{align} $$ 此时d-q系控制相互解耦,很容易可以得到电压与电流传递函数满足 $$ G(S)=\frac{I(S)}{U(S)}=\frac{1}{R+LS} $$ 于是可以在simulink中搭建电机控制结构框图如下图所示,由PI控制环节、由单片机定时器装载产生的滞后环节和电机模型共三个环节;其中$T_S=\frac{1}{30000}s$为电流环执行周期,取电机参数$L=6.27e^{-6}H,R=0.017\Omega$ 当Kp=1,Ki=0时,阶跃响应效果如图所示, #### 任务要求: - 子任务1:根据task8文件夹中的.slx文件,调整PI控制参数,使其单位阶跃响应调节时间小于0.5ms,超调小于5%,无稳态误差。 - 子任务2:根据自控原理所学知识给出PI控制器设计思路,没学过自控的同学可以结合第一周任务“PID控制程序编写及封装”中的调节方法,给出手动调节思路。 - 子任务3:将调整后的示波器图像和任务2中的设计思路以PDF 形式提交到邮箱。 - 将以上内容放在task8文件夹下与其他任务的文件一起打包为zip文件地址为zip文件命名格式为**{你的名字}第三周测试题.zip**),提交到邮箱`bhjqrdkzz2022@163.com` ### 9.运动学解算 #### 任务简介: 底盘运动学分解是控制组必备技能。在今年的Robocon比赛中,北航机器人队采用了3舵轮运动底盘,我们需要对底盘进行运动学分解,以便控制机器人进行运动 #### 任务说明: - 子任务1:推导如图1所示三舵轮底盘将**车体坐标系**下的目标速度大小、速度方向与角速度大小(方向默认俯视顺时针为正)解算到三舵轮转动**角速度和角度**的公式,写出推导过程并说明各个参数的含义。部分说明与设定参数如下: - 子任务2:在上一问的基础上,考虑当给出**世界坐标系**下的机器人期望速度矢量与角速度矢量时,解算出三舵轮转动的**角速度和角度**。给出公式,写出推导过程并说明参数含义。 - 子任务3:在ChassisMotion.c 与 ChassisMotion.h 中,根据注释提示补全代码,实现三轮全向轮底盘各轮所需转速的解算任务。 - 将以上内容放在task9文件夹下与其他任务的文件一起打包为zip文件地址为zip文件命名格式为**{你的名字}第三周测试题.zip**),提交到邮箱`bhjqrdkzz2022@163.com` ### 10.FreeRTOS #### 任务简介: Robocon的赛场上,机器人同时处理的任务、同时传递的消息繁多,这时候继续采用前后端的编程模式和全局变量的消息形式,就存在一定的局限性,不利于机器人控制逻辑的实现和代码的可维护性。这时候就需要使用嵌入式操作系统。在北航机器人队中,采用的嵌入式操作系统为FreeRTOS,几乎所有控制组的成员都需要掌握FreeRTOS的使用方法。 在之前,我们已经学习过了电机驱动的FOC控制方式,其中的巧妙深入人心。但是在此类伺服驱动能够运行三环控制之前,校准环节是必不可少的。本周的任务需要使用FreeRTOS简单实现编码器校准的工作。 中文版资料(视频和例程以及书籍等)主要参考正点原子(FreeRTOS开发手册)与野火哥(FreeRTOS内核实现与应用开发实战),英文原版资料科参考FreeRTOS官网和官方手册。 #### 任务前提: ##### 编码器校准流程: ①控制电机转向指定电角度$\theta_e$,当电机稳定指向该角度时,记录编码器数值。 ②小量改变指定电角度为$\theta_e+\Delta\theta$,重复上述过程。 ③由于编码器数值是离散的整数(大小范围为0~1024),因此只要电角度改变足够小,可以做到1个编码器数值对应多个电角度数值。此时,对相同编码器数值$i$对应的多个编码器数值$\theta_{ei}$取平均值$\hat\theta_{e}$,得到$encoder[i]=\hat\theta_{e}$ ④处理完全部数据,得到数组encoder[1024]。 ##### 定向电流环任务: ①根据$i_{a},i_{b},i_{c}$和$\theta_{e}$,利用Park变换和Clark变换,得到$i_{d},i_{q}$。 ②将$i_{d},i_{q}$带入PID中计算(2个PID分别计算,得到输出$u_{d},u_{q}$)。 ③高频运行,通常运行频率为校准任务20倍以上。 ##### 校准任务: ①迭代期望电角度值$\theta_e+\Delta\theta$。 ②读出此时编码器数值$i$。 ③重复以上两步,直到电角度值全部遍历。处理所有数据,得到encoder[1024]。 #### 任务说明: - 子任务1:查阅相关资料,简要谈谈为什么要使用嵌入式操作系统?谈谈你对操作系统FreeRTOS中信号量的功能的理解?字数不超过200字。 - 子任务2:任选一款STM32芯片,新建Keil工程并编写STM32程序,尝试移植FreeRTOS操作系统。然后根据上述流程图,创建2个任务,实现编码器校准的大致过程。具体提示如下: - 校准任务 1. 创建“校准任务”,运行频率约为50Hz,任务优先级自选,较低即可。 校准任务每次循环时,更新全局变量$\theta_{e}$:(设极对数为1,编码器数值范围0~1024,相同i对应约20个点角度值) $$ \theta_{e}(n+1)=\theta_{e}(n)+\Delta\theta(\Delta\theta=\frac{2\times\pi\times 1}{1024\times20}=3\times10^{-4}) $$ 2. 更新全局变量$\theta_ e$后,“校准任务”进入阻塞态,延时为20ms。 3. 延时20ms后,调用GetRawAngle()函数,该函数不用编写,直接调用即可。其返回值为uint16_t类型,含义为当前编码器数值i。 4. 重复以上过程,直到当$\theta_{e}>2\pi$时,停止循环。此时计算encoder[1024]值: $$ encoder[i]=\frac{\sum_{j=1}^n\theta_{e}(对应编码器为i的电角度值)}{n} $$ 5. 计算完毕后挂起该任务。 - 定向电流任务 1. 创建“定向电流环任务”,运行频率约1kHz,任务优先级需高于“校准任务”。 2. 调用函数GetCurrent()得到三相电流$i_a,i_b,i_c$。再根据和$i_a,i_b,i_c$和$\theta_ e$,根据前几周学习的FOC内容,调用提供的ClarkTransform()、ParkTransform()函数,得到$i_d,i_q$。接着将分别带入$i_d,i_q$各自的PID运算中,以PID计算的结果为输出$u_d,u_q$(Kp、Ki数值任取)。最后调用函数ApplyVoltDQ()输出$u_d,u_q$。输出$u_d,u_q$后,认为该次循环结束,该任务进入阻塞态,延时为1ms。 - 需注意:当“校准任务”要挂起时,先挂起“定向电流任务”。 #### 任务要求 程序要有一定的可读性,包含适当的注释;即使没能完成任务,也请提交上来,并且写明原因以及完成的进度情况。 可直接调用而无需编写的函数如下 | 返回类型 | 函数名称 | 调用方式 | | -------- | --------------------------------- | ------------------------------------------------------------ | | float * | GetCurrent() | float cur = GetCurrent(); $i_a$=cur; $i_b$=(cur + 1); $i_c$=(cur + 2); | | float * | ParkTransform() ClarkTransform() | 与上函数类似 | | void | ApplyVoltDQ() | ApplyVoltDQ($u_d$,$u_q$); | | uint16_t | GetRawAngle() | i = GetRawAngle(); | 将以上内容放在task10文件夹下与其他任务的文件一起打包为zip文件地址为zip文件命名格式为**{你的名字}第三周测试题.zip**),提交到邮箱`bhjqrdkzz2022@163.com`