Skip to content

Latest commit

 

History

History
251 lines (205 loc) · 14 KB

TotalControl.md

File metadata and controls

251 lines (205 loc) · 14 KB

机器狗整体控制

0、写在前面:

  1. 未特殊说明,一切树莓派操作皆在 小黑框(终端) 中进行STM32单片机的操作皆在创建的 Keil 项目中进行
  2. 项目创建方法:Keil创建STM32项目并烧录使用
  3. 关于初始化函数的位置
    • (不推荐)直接写在 main.c
    • (推荐)创建单独的 XXX.cXXX.h 用于放置相关函数,分别放在 Core 文件夹下的 IncSrc里,前一个文件夹用于放 XXX.h,后者放 XXX.c
    • (较推荐)创建单独的 XXX.cXXX.h 用于放置相关函数,单独额外创建文件夹用于放置自写的文件(记得添加到项目的 include 中)
      如图

1、控制关系

通过树莓派接收图片信息并测量标志距离,根据所得距离信息与预设 危险距离 对比,启动串口,根据是否在 危险距离以内 发送 停止启动 信息到单片机,单片机根据接收的启停信号来重新开始运动或停止运动,运动过程中机器狗的步伐完全由单片机控制

如图

2、系统初始化

详见 树莓派初始化文档Keil创建STM32项目并烧录使用

3、树莓派摄像头监视与距离获取

如图

具体步骤如下

  1. 定时拍摄
    • 定时任务使用(参考 课设 第 6 到 8 页的 定时任务(Cron) 部分)
    • 拍摄(参考 课设 第 8 到 10 页的 图片截取 部分)
    • 组合:
      • 创建定时使用的脚本(参考下方 代码 1
      • 脚本添加内容(参考下方 代码 2
      • 将定时任务里的 command 替换为下方 代码 3 的内容
  2. 自启动测距
    • 自启动(参考 开机启动使用
    • 距离测量(参考 课设 第 10 到 13 页的 图片处理 部分)
    • 组合:
      • 创建测距的 python 文件(参考下方 代码 4
      • 课设 第 8 到 10 页的 图片截取 部分的 测距完整程序 下的代码框里的内容全粘贴到刚创建的 XXX.py 文件里(注意:frame = cv2.imread(filepath,flags) 里面的 filepath 改为上一部分 定时拍摄 里生成的 tmp.jpg 文件的路径)
      • 按下图更改 .service 文件的内容
        如图
# 代码 1
# 创建定时使用的脚本
nano XXX.sh   # XXX 是脚本名,`.sh` 是脚本文件的后缀
# sudo nano XXX.sh   # 上一行命令失败使用这个
# 代码 2
# 脚本添加内容 - 直接复制粘贴到上一步命令成功后所在的界面即可
# 功能:循环拍摄,循环次数为 1min/(拍摄延时 + 1 到 0.5 秒)
# 循环次数数值可以大,定时任务会自动打断上一轮未完成的定时任务
# ----------- 只添加这条线以下的内容 ------------------
#! /bin/bash
for i in $(seq 1 30) # 控制循环次数用
do
    libcamera-jpeg -o tmp.jpg -t 1000
done
/你的路径/XXX.sh   # 最好写从根目录到该文件的绝对路径,不容易出错
# 代码 4
# 创建测距的 python 文件
nano XXX.py   # XXX 是脚本名,`.py` 是 python 文件的后缀
# sudo nano XXX.py   # 上一行命令失败使用这个

参考资料如下

  1. 开机启动使用
    • 自启动服务应在 /etc/systemd/system/ 文件夹下,但为了方便,服务文件在被自启动的文件所在文件夹也有一份备份,请在该备份中更改,并在更改后将其复制到应在的文件夹,如 sudo cp distance_measurement.service /etc/systemd/system/distance_measurement.service
  2. 定时使用脚本
    • 最低使用间隔:1min -> 可通过循环命令和 sleep 命令解决
    • cron 服务启、停、状态查看
    • 注意:
    • 调用的脚本中一定要使用绝对路径,或在内部自行定义路径,一定不要直接使用全局的环境变量,否则既不会报错,也不会正常运行
    • cron 命令调用生成的内容有时候会自带写保护,影响不大
  3. 摄像头使用
  4. 特定图形(颜色块)测距

4、串口信号发送与接收

4.1、树莓派的串口发送

具体实现

  • 初始化开启串口
  • 使用 python 代码控制串口发送
    • python 环境配置并激活虚拟环境
    • 创建 .py 文件并在文件中添加如下代码(详情查看下方 代码 4.1.1代码 4.1.2
    • 运行刚才的文件(详情查看下方 代码 4.1.3
    • 接收查看:树莓派与电脑正确连接后打开任意串口助手软件开启串口后皆可看见结果
# 代码 4.1.1
# 创建名为 python 文件;xxx 是文件名,可更改;`.py` 不允许更改
nano xxx.py
# 有些文件夹创建文件会要求根权限,则这么写,当然,最好不要在这种文件夹下操作
# sudo nano xxx.py

# 运行后会自动进入创建的文件
# 代码 4.1.2
# 以下代码添加到刚刚创建的文件(创建后会自动进入)
import serial  # 添加串口包

ser = serial.Serial("/dev/ttyAMA0", 115200)  # 设置串口端口和波特率,前者自行查看,一般用本部分的串口初始化者和我的是一样的
ser.flushInput()  # 清除缓存
ser.write("Hello World\r\n".encode())  # 发送数据  \r\n可以实现换行  encode()默认是'utf-8'
# ctrl + o,回车:保存
# ctrl + x:退出该文件
# 代码 4.1.3
# 运行刚刚的文件
python3 xxx.py   # python3 文件名

参考资料

4.2、单片机的串口接收

使用步骤

  1. 正确接线
    • 一般串口接线都用四根线,本单片机也是选择四线制,下面是两个设备(设备A - 设备B)的串口连线,A 和 B 分别是什么无所谓
    • 5v - 5v
    • GND - GND
    • RX/RXD - TX/TXD
    • TX/TXD - RX/RXD
    • 本单片机和转接模块(USB 转 TTL)接线如下
      如图
  2. 开启对应配置并检查文件完整性
  3. 串口初始化(详见 myUart.c 注释)
    • 关于代码重写:库文件的函数不能修改,故为了实现初始化,必须重写;同时,这种不允许修改的函数是个 __weak (即弱定义)函数,在自写同名函数时将不会使用带 __weak 的函数
      如图
  4. 两个函数解决串口常规使用问题
    • 串口发送函数:HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
      • UART_HandleTypeDef *huart:已经初始化的串口结构体
      • const uint8_t *pData:将要发送的字符串
      • uint16_t Size:将要发送的字符串的大小
      • uint32_t Timeout:超时响应,超过设置的时间无论是否发送完成将会跳出串口发送
    • 串口接收函数:HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
      • UART_HandleTypeDef *huart:已经初始化的串口结构体
      • const uint8_t *pData:将要接收的字符所存放的指针
      • uint16_t Size:将要接收的字符的大小
      • uint32_t Timeout:超时响应,超过设置的时间无论是否接收完成将会跳出串口接收
  5. 另外:串口同样可以使用中断来控制,不过由于暂时无该需求,就未研究

参考资料

5、单片机的 PWM 运动控制

使用步骤

5.1、简述

  • 引脚输出的 PWM 信号控制 180 度舵机的 输出角度
  • 使用 高级定时器 根据当前应该输出的 脚步状态 控制引脚输出 PWM 信号
  • 使用 基本定时器 根据 时间 控制当前应该输出的 脚步状态

5.2、输出角度PWM 信号对应关系

  1. 舵机选择
    • MG90S-180 度舵机
    • 【淘宝】限时满70减3 https://m.tb.cn/h.gSzxWhPoudoI3sg?tk=Y7Tf3bsHA3S MF6563 「SG90 9G经典舵机 180/360度 数字舵机云台遥控飞机马达固定翼航模」 点击链接直接打开 或者 淘宝搜索直接打开
  2. 数据
    • 根据卖家所给数据来看,每次输入的信号不低于 20ms,信号占空比在 25% 到 75% 之间有效
      如图 如图

5.3、高级定时器 控制 PWM 输出信号

如图

  1. 初始配置
    • 开启对应配置并检查文件完整性:同串口,不过开启的是 TIM
    • 代码配置:详见 myYIM.c高级定时器使用 部分的注释
    • 关于死区:在生成的参考波形 OCxREF 的基础上,可以插入死区时间,用于生成两路互补的输出信号 OCx 和 OCxN,死区时间的大小必须根据与输出信号相连接的器件及其特性来调整。
      如图
    • 关于通道与引脚对应:这次我们使用的是 TIM8,通道 1、2、3、4 分别对应引脚 PC6、PC7、PC8、PC9(也可自行调整,不过只有这几个在本开发板上引出针脚了,图中的 CHx 是各个通道)
      如图 如图
  2. 使用
    • 先在 main.c 使用自写的 MX_TIM_Advance_Init 初始化 PWM
    • 后通过 __HAL_TIM_SetCompare(__HANDLE__, __CHANNEL__, __COMPARE__) 调节占空比
      • __HANDLE__:调节的定时器,这里填 htim_advance 即可,已经设置好了 extern 关键字
      • __CHANNEL__:通道号,调哪个通道写哪个即可,我的代码中使用 LEF_SMALL_RIGHT 之类的是因为在 main.h#define 了,方便代码和实际物件的对应
      • __COMPARE__:调整后的占空比数值,实际占空比为 __COMPARE__/2^16

5.4、基本定时器 控制 脚步状态

  1. 初始配置
    • 开启对应配置并检查文件完整性:同串口,开启的也是 TIM
  2. 使用/撰写方法
    • 根据 启动文件 的中断向量表(146 行)在 中断处理文件 里编写对应的 中断处理函数回调函数
    • 在合适的文件中(一般单独创建一个文件用于放置定时器相关配置和使用),编写定时器的初始化函数
      • 详见 myYIM.c基本定时器使用 部分的注释
    • main.c 中调用定时器初始化函数就完成了
  3. 控制脚步
    • 通过前面提到过的 __HAL_TIM_SetCompare(__HANDLE__, __CHANNEL__, __COMPARE__) 控制输出的 PWM 占空比控制对应舵机的角度
    • 将机器狗走动时的体态分解,使其成为一个个状态,每个状态中的各个舵机输出的 PWM 信号不同,这样,一个状态就能变成一个函数,一个调节各个舵机到正确 PWM 值的函数
    • 创建 Robot_Control 函数,其核心是内部带有 static 关键字的参数 state,代表各个状态,state 是多少就会调用多少号状态
    • 定时器回调函数内调用 Robot_Control 函数,每次调用都会更新 state,又由于该参数是 static ,每次调用 Robot_Control 函数时不会清零,而是会在原先的 state 值基础上进行更新

参考资料