更新银星机器人文档

main
UESTCsecurity 2024-01-24 12:08:34 +08:00
parent 1828a774bb
commit dfeedf5920
14 changed files with 1863 additions and 22 deletions

View File

@ -0,0 +1,70 @@
测2.4速.3原⻓理话短说 传感器及编码器的
霍尔传感器是电机最常⽤的定位和测速装置.今天我们就来简单解释⼀下,霍尔传感器和
编码器的测速原理.
⼀ 基本原理
对于1个两极性的径向磁环, 当它的附近有1个霍尔传感器时,磁环转⼀圈可以输出1个脉
冲.
那么假设在1s时间内,我收到1个脉冲,那么转速就是1/s,也就是60RPM.RPM指的是每
分钟的圈数量.
2.4.3 ⻓话短说 传感器及编码器的测速原理 1
对于1个2极性径向磁环, 当它的附近有2个霍尔传感器时,磁环转⼀圈,每个传感器可以
输出1个脉冲.那么假设在1s时间内,收到传感器A发出的1个脉冲,那么电机的转速就是
1/s/1=(2*60/2)/M =60RPM.传感器B也会发⼀个脉冲,但是A和B的发出的脉冲会有⼀个
90°的相位差.
那为什么要⽤2个霍尔传感器呢?有⼀个好处,就是可以测量出⽅向.是A先输出脉冲,还
是B先输出脉冲.就代表着电机是顺时针旋转(转转),还是逆时针旋转.
2.4.3 ⻓话短说 传感器及编码器的测速原理 2
对于1个22极性径向磁环, 当它的附近有2个霍尔传感器时,磁环转⼀圈,每个传感器可以
输出11个脉冲.那么假设在1s时间内,我收到11个脉冲,那么转速就是11/s/11=
(11*60/11)/M=60RPM.
以上说的只是单独读取脉冲的个数,,我们可以⽤定时器的输⼊捕获引脚或者I/O的外部
中断数这个脉冲的个数.
2.4.3 ⻓话短说 传感器及编码器的测速原理 3
stm32的定时器可以设置成编码器模式,需要明⽩三点:
1.⾸先定时器在编码器模式下,它测量的已经不是脉冲的个数,⽽是边沿的个数.[如图]
2.⽽且因为A和B的信号是有相位差,编码器可以同时记录AB两个传感器产⽣的边沿数
量.
3.定时器设定为编码器模式时,其CNT直接⽤于记录由AB传感器输⼊的边沿个数,直接
读取CNT的值,就是边沿的个数.正转时CNT向上计数,反转时,CNT向下计数.
2.4.3 ⻓话短说 传感器及编码器的测速原理 4
这样的话如果电机转⼀圈,定时器的CNT就可以计数44个.正转⼀圈+44,反转⼀圈-44.
样例程序和样板电路原理图及PCB⽂件在视频简介的链接⾥.2元rmb,谢谢⽀持.
⼆ 编程实践
配置顺序:
(1)使⽤定时器2配置成编码器模式,配置如下.
[简单讲解]
(2)使⽤定时器3定⼀个1ms的定时中断.
每次读取TIMER2的CNT数值,存放在变量encoder_val内.然后清零CNT.这样读出来的
就是电机速度了,注意此时单位是N/ms
然后要转化为标准的转速RPM.计算电机转速motor_speed.
但是⼀般⼩⻋电机是有⻮轮箱的 我们这 motor_speed=encoder_val*1000*60/44 RPM.,
个⻮轮箱的⻮⽐是19,也就是电机转19圈,⻮轮箱转1圈所以电机真正输出的转速是:
motor_speed=encoder_val*1000*60/44/19 RPM.
三 实验任务:
(1) 观察编码器⼀圈是否是计数+-44 .
(2)如何 测量转速 清零就可以了
如何 *(3) 记录反向转速 负数
2.4.3 ⻓话短说 传感器及编码器的测速原理 5

File diff suppressed because one or more lines are too long

View File

@ -82,17 +82,17 @@
<Book> <Book>
<Number>0</Number> <Number>0</Number>
<Title>Base Board Schematics (MCBSTM32E)</Title> <Title>Base Board Schematics (MCBSTM32E)</Title>
<Path>D:\Program Files\Keilv5\ARM\PACK\Keil\STM32F1xx_DFP\1.1.0\Documents\mcbstm32e-base-board-schematics.pdf</Path> <Path>C:\Keil_v5\ARM\PACK\Keil\STM32F1xx_DFP\1.1.0\Documents\mcbstm32e-base-board-schematics.pdf</Path>
</Book> </Book>
<Book> <Book>
<Number>1</Number> <Number>1</Number>
<Title>Display Board Schematics (MCBSTM32E)</Title> <Title>Display Board Schematics (MCBSTM32E)</Title>
<Path>D:\Program Files\Keilv5\ARM\PACK\Keil\STM32F1xx_DFP\1.1.0\Documents\mcbstm32e-display-board-schematics.pdf</Path> <Path>C:\Keil_v5\ARM\PACK\Keil\STM32F1xx_DFP\1.1.0\Documents\mcbstm32e-display-board-schematics.pdf</Path>
</Book> </Book>
<Book> <Book>
<Number>2</Number> <Number>2</Number>
<Title>User Manual (MCBSTM32E)</Title> <Title>User Manual (MCBSTM32E)</Title>
<Path>D:\Program Files\Keilv5\ARM\PACK\Keil\STM32F1xx_DFP\1.1.0\Documents\mcbstm32e.chm</Path> <Path>C:\Keil_v5\ARM\PACK\Keil\STM32F1xx_DFP\1.1.0\Documents\mcbstm32e.chm</Path>
</Book> </Book>
<Book> <Book>
<Number>3</Number> <Number>3</Number>

Binary file not shown.

Binary file not shown.

View File

@ -14,7 +14,7 @@ from PyQt5.QtCore import QObject,pyqtSignal
import pb import pb
import threading import threading
port = "COM7" port = "COM6"
pypibot.assistant.enableGlobalExcept() pypibot.assistant.enableGlobalExcept()
# log.enableFileLog(log_dir + "ros_$(Date8)_$(filenumber2).log") # log.enableFileLog(log_dir + "ros_$(Date8)_$(filenumber2).log")

View File

@ -654,18 +654,18 @@ class Ui_pb(object):
def retranslateUi(self, pb): def retranslateUi(self, pb):
_translate = QtCore.QCoreApplication.translate _translate = QtCore.QCoreApplication.translate
pb.setWindowTitle(_translate("pb", "PIBOT Test Tool")) pb.setWindowTitle(_translate("pb", "UPBOT机器人配置工具"))
self.label_2.setText(_translate("pb", "Model Name")) self.label_2.setText(_translate("pb", "机器人模型"))
self.label_3.setText(_translate("pb", "IMU Type")) self.label_3.setText(_translate("pb", "IMU型号"))
self.label_6.setText(_translate("pb", "MotorRatio")) self.label_6.setText(_translate("pb", "电机减速比"))
self.label_motor_ratio.setText(_translate("pb", "0")) self.label_motor_ratio.setText(_translate("pb", "0"))
self.label.setText(_translate("pb", "Diameter")) self.label.setText(_translate("pb", "轮子直径(mm)"))
self.label_wheel_diameter.setText(_translate("pb", "0")) self.label_wheel_diameter.setText(_translate("pb", "0"))
self.label_4.setText(_translate("pb", "Encoder")) self.label_4.setText(_translate("pb", "编码器分辨率"))
self.label_encoder_res.setText(_translate("pb", "0")) self.label_encoder_res.setText(_translate("pb", "0"))
self.label_5.setText(_translate("pb", "WheelTrack")) self.label_5.setText(_translate("pb", "轮距(mm)"))
self.label_wheel_track.setText(_translate("pb", "0")) self.label_wheel_track.setText(_translate("pb", "0"))
self.groupBox.setTitle(_translate("pb", "Reverse Direction Flag")) self.groupBox.setTitle(_translate("pb", "翻转方向标志"))
self.checkBox_motor1.setText(_translate("pb", "Motor1 ")) self.checkBox_motor1.setText(_translate("pb", "Motor1 "))
self.checkBox_motor2.setText(_translate("pb", "Motor2")) self.checkBox_motor2.setText(_translate("pb", "Motor2"))
self.checkBox_motor3.setText(_translate("pb", "Motor3")) self.checkBox_motor3.setText(_translate("pb", "Motor3"))
@ -683,22 +683,22 @@ class Ui_pb(object):
self.label_kp.setText(_translate("pb", "0")) self.label_kp.setText(_translate("pb", "0"))
self.label_18.setText(_translate("pb", "KO")) self.label_18.setText(_translate("pb", "KO"))
self.label_ko.setText(_translate("pb", "0")) self.label_ko.setText(_translate("pb", "0"))
self.label_19.setText(_translate("pb", "Interval")) self.label_19.setText(_translate("pb", "间隔(ms)"))
self.label_pid_interval.setText(_translate("pb", "0")) self.label_pid_interval.setText(_translate("pb", "0"))
self.groupBox_2.setTitle(_translate("pb", "Speed Limit")) self.groupBox_2.setTitle(_translate("pb", "速度限制"))
self.label_22.setText(_translate("pb", "VY")) self.label_22.setText(_translate("pb", "VY(cm/s)"))
self.label_vy_max.setText(_translate("pb", "0")) self.label_vy_max.setText(_translate("pb", "0"))
self.label_21.setText(_translate("pb", "VX")) self.label_21.setText(_translate("pb", "VX(cm/s)"))
self.label_vx_max.setText(_translate("pb", "0")) self.label_vx_max.setText(_translate("pb", "0"))
self.label_23.setText(_translate("pb", "VA")) self.label_23.setText(_translate("pb", "VAZ(0.01rad/s)"))
self.label_va_max.setText(_translate("pb", "0")) self.label_va_max.setText(_translate("pb", "0"))
self.label_20.setText(_translate("pb", "CMD Time")) self.label_20.setText(_translate("pb", "CMD Time(ms)"))
self.label_cmd_lasttime.setText(_translate("pb", "0")) self.label_cmd_lasttime.setText(_translate("pb", "0"))
self.pushButton_load.setText(_translate("pb", "Load")) self.pushButton_load.setText(_translate("pb", "Load"))
self.pushButton_set.setText(_translate("pb", "Set")) self.pushButton_set.setText(_translate("pb", "设置"))
self.pushButton_read.setText(_translate("pb", "Read")) self.pushButton_read.setText(_translate("pb", "读取"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("pb", "Tab 1")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("pb", "Tab 1"))
self.groupBox_4.setTitle(_translate("pb", "Motor")) self.groupBox_4.setTitle(_translate("pb", "电机设置"))
self.label_7.setText(_translate("pb", "Motor1")) self.label_7.setText(_translate("pb", "Motor1"))
self.label_set_pwm1.setText(_translate("pb", "0")) self.label_set_pwm1.setText(_translate("pb", "0"))
self.label_10.setText(_translate("pb", "Encoder Feedback")) self.label_10.setText(_translate("pb", "Encoder Feedback"))
@ -733,7 +733,7 @@ class Ui_pb(object):
self.label_31.setText(_translate("pb", "VA")) self.label_31.setText(_translate("pb", "VA"))
self.pushButton_start_2.setText(_translate("pb", "start")) self.pushButton_start_2.setText(_translate("pb", "start"))
self.pushButton_stop_2.setText(_translate("pb", "stop")) self.pushButton_stop_2.setText(_translate("pb", "stop"))
self.groupBox_5.setTitle(_translate("pb", "IMU")) self.groupBox_5.setTitle(_translate("pb", "IMU实时数据"))
self.label_28.setText(_translate("pb", "MAGN")) self.label_28.setText(_translate("pb", "MAGN"))
self.label_magn_y.setText(_translate("pb", "0.000")) self.label_magn_y.setText(_translate("pb", "0.000"))
self.label_26.setText(_translate("pb", "GYRO")) self.label_26.setText(_translate("pb", "GYRO"))

View File

@ -0,0 +1,70 @@
#### 1.银星机器人参数
##### 1.1 基本尺寸参数
银星机器人有两个大齿轮,分别在电机和轮子上,经过尺寸的测量发现两个齿轮大小一样,应该是`1:1`的关系。
| 类别 | 参数 | 数值 |
| -------------- | ------- | -------------- |
| 轮子直径 | `mm` | `240` |
| 轮距 | `mm` | `420` |
| 编码器分辨率 | - | 未知 |
| 电机减速比 | - | `1:90` |
| 减速箱默认转速 | `RPM` | 54 |
| 电机默认转速 | `r/min` | 4200 |
| 电机默认方向 | `CCW` | 逆时针方向旋转 |
| 额定电压 | 伏特 | 24 |
| 额定电流 | 安培 | 1.6 |
| 额定功率 | 瓦特 | 22 |
##### 1.2 接线方式
在`Pibot`开发板定义中,对于二轮差分模型。`Motor1`和`Motor2`分别对应的是左轮和右轮,关系如下表所示:
| 项目 | 类别 | `Pibot`端口 \ `Gebot`端口 | 说明 |
| -------- | ------------------- | --------------------------- | ---------- |
| `MOTOR1` | 左轮 | `U5` \ `PL(Port Left)` | 连接端口 |
| `MOTOR2` | 右轮 | `U4` \ `PR(Port Right)` | 连接端口 |
| `LEN` | 左轮`PWM`(橙色线) | `PA3` | 速度控IO |
| `LP` | 左轮方向 (绿色线) | `PB13` | 方向控制IO |
| `REN` | 右轮`PWM`(灰色线) | `PA2` | 速度控IO |
| `RP` | 右轮方向 (紫色线) | `PB14` | 方向控制IO |
#### 1.3 默认方向
`Pibot`在运动学解算的时候,是按照每个轮子单独考虑的。默认情况下,轮子轴的方向指向左侧的`y`轴,轮子的前进方向前方的`x`轴方向。所以按照运动学解算,小车在前进的时候,左轮是需要“反向”旋转的。
为了更好理解,我们假设电机上面有标注默认的正负号,假设电机默认是顺时针旋转(轴心朝前)。当我们把电机安装在左轮的时候,给默认的电压方向,那么左轮是倒退的,所以我们需要给"负值"的`PWM`,即是让轮子反方向旋转。当然,`PWM`本身是一个非负的数值,负值表示其方向作用。
```C
// 如果PWM为正值
if (pwm_value > 5) {
// 控制电机运动方向
GPIO_SetBits(GPIOB, GPIO_Pin_13);
// 设置电机速度
PB_Set_PWM(TIM2, 4, (uint16_t)pwm_value);
// 如果PWM为负值
}else if (pwm_value < -5) {
// 控制电机运动方向
GPIO_ResetBits(GPIOB, GPIO_Pin_13);
// 设置电机速度
PB_Set_PWM(TIM2, 4, (uint16_t)-pwm_value);
}
```
| 类别 | 方向 | 数值 | 说明 |
| -------- | -------- | ---- | ---------------------------------------- |
| 左电机 | 小车前进 | 负值 | 小车在给前进命令时`PWM`实际是负值。 |
| 左编码器 | 小车前进 | 负值 | 小车给前进命令时,小车编码器总值负增长。 |
| 右电机 | 小车前进 | 正值 | 小车在给前进命令时`PWM`实际是正值。 |
| 右编码器 | 小车前进 | 正值 | 小车给前进命令时,小车编码器总值正增长。 |
##### 1.4 编码器到速度的换算
目前银星机器人采用的是霍尔编码器但是其磁环的参数是未知的。常见的磁环的有22个极性。那么电机转动一圈下来就会产生44个脉冲计数。霍尔编码器原理详情见《霍尔编码器原理》。
```c
// 运动距离 = (编码器数值 / 编码器一圈脉冲计数) * 减速比 * 轮子直径 / 2 * PI
dis = (encoder_num / ENCODER_RATIO) * reduction ratio * wheel_diameter / 2 * PI;
```