forked from logzhan/RobotHardware-UESTC
更新银星机器人文档
parent
1828a774bb
commit
dfeedf5920
|
@ -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
|
@ -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.
Binary file not shown.
Binary file not shown.
|
@ -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")
|
||||||
|
|
|
@ -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"))
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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;
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in New Issue