0%

舵机转向小车运动参数解算

用于计算舵机转向小车前轮转向控制模型的计算

舵机转向小车运动参数解算

编码器每轮783计数

轮子周长 0.2m

编码器计时周期 30ms

编码器长度换算 编码器值/4000 m

编码器速度换算 编码器值/4000/0.03 m/s

后轮轴长0.16m

前后轮差0.19m

1.后轮电子差速

后轮两个轮子分别使用两个编码器电机 通过pid算法可以精确的控制电机转速

车模在转弯时 两个后轮走过的路程不一致 因此需要差速控制 一般汽车上有专业的机械差速器控制差速

差速算法以后再补

2.前轮角度控制

对于一些车模来说 前轮是有一个舵机带动 而舵机的角度又是会和前轮偏转角度呈一个复杂关系 有的车模控制程序简单的用一个线性关系去解算 会导致误差较大 对舵机连杆进行建模 然后通过运动学求解析解就可以得到一个良好的控制模型式

这是我们的控制模型 一般来说 分为以下两种 先考虑第二种

image-20210725164933373

image-20210725165030345

控制原理

image-20210725165102544

二维绘图

image-20210725165127313

此处AB=i 图画i/j不清楚 此处绘制$z_C=z_D=0$实际也可不为零(见下文)

image-20210725165153416

其中 圆A和圆D的位置确定 圆心和半径可以测量出来 j的长度确定

因此 B和C满足距离公式
$$
(x_B-x_C)^2+(y_B-y_C)^2+(z_B-z_C)^2=j^2①
$$
同时 B和C分别满足圆的公式
$$
x_B^2+z_B^2=i^2②\
y_A=y_B=0(坐标原点设定在A上)\
(x_C-x_D)^2+(y_C-y_D)^2=k^2③\
z_C=z_D
$$
将①展开 分别减去②和③ 并带入已知条件 可得下式
$$
z_D^2-2x_Bx_C-2z_Bz_C-x_D^2-y_D^2+2x_Cx_D+2y_Cy_D=j^2-k^2-i^2\
2x_Bx_C+2z_Bz_C=i^2-j^2+k^2-x_D^2-y_D^2+z_D^2+2x_Cx_D+2y_Cy_D
$$
如下图做辅助线(2021年12月2日记 此处有误 投影后BC不为j)

image-20210725165254994
$$
x_C=-l\cos(a)\
z_C=l\sin(a)\
l=\sqrt{x_C^2+z_C^2}\
x_B=i\sin(b)\
z_B=i\cos(b)
$$
带入上式
$$
2il\sin(a)\cos(b)-2il\cos(a)\sin(b)=i^2-j^2+k^2-x_D^2-y_D^2+z_D^2+2x_Cx_D+2y_Cy_D\
\sin(a-b)=\frac{i^2-j^2+k^2-x_D^2-y_D^2+z_D^2+2x_Cx_D+2y_Cy_D}{2il}\
b=a-\arcsin(\frac{i^2-j^2+k^2-x_D^2-y_D^2+z_D^2+2x_Cx_D+2y_Cy_D}{2il})
$$
其中
$$
x_C=x_D+k\sin(c)\
y_C=y_D-k\cos(c)\
z_C=z_D\
a=\arctan(z_C/x_C)\
d-e=c
$$
image-20210725165332840

e是轮子的偏转角

d是轮子偏转角为0时 k与y轴负半轴的夹角 是结构自带的角度

image-20210725165407371

算法

爷烦了 不写了 直接贴代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""
import math
import numpy as np
i=0.02
#r2=0
k_y=0.024#y方向长
k_x=0.0045#x方向长
k_z=0#z方向长
k=math.sqrt(k_x**2+k_y**2+k_z**2)
A=(0,0,0)
D_x=-0.063
D_y=0.034
D_z=0
D=(D_x,D_y,D_z)

C_x_0=D_x+k_x#零位置坐标
C_y_0=D_y-k_y
C_z_0=D_z-k_z
B_x_0=0
B_y_0=0
B_z_0=i

j=math.sqrt((C_x_0-B_x_0)**2+(C_y_0-B_y_0)**2+(C_z_0-B_z_0)**2)

d=math.atan(k_x/k_y)

li=np.zeros(shape=(10001,2))

for tmp in range(-5000,5001,1):
e=tmp/100/180*math.pi
c=d-e
C_x=D_x+math.sin(c)*k
C_y=D_y-math.cos(c)*k
C_z=D_z
a=math.atan(C_z/C_x)
l=math.sqrt(C_x**2+C_z**2)
try:
b=a-math.asin((i**2-j**2+k**2-D_x**2-D_y**2+D_z**2+2*C_x*D_x+2*C_y*D_y)/(2*i*l))

li[tmp+5000,0]=e
li[tmp+5000,1]=b/math.pi*2000
except:
print('err')
#li.append((tmp/100,b/math.pi*180))
print('ok')

drawx=li[:,0]
drawy=li[:,1]

import matplotlib.pyplot as plt

#创建绘图图表对象,可以不显式创建,跟cv2中的cv2.namedWindow()用法差不多
plt.figure('Draw')

plt.plot(drawy,drawx)

plt.draw()

运行结果

image-20210725165453195

image-20210819203202442

在中间很长一段都有非常好的线性近似 直接做个线性就行

以上只考虑了舵机直连轴(左前轮)的运动状况 如果要求转向半径 可以参考阿克曼转向相关内容