目录
从零开始的静改动工程
现阶段完成到底盘部分,由于tb套件的二次开发空间有限,所以开始考虑自己制作一版静改动解决方案。第一次做静改动,对空间使用的把握没有b数,所以就不考虑苏系车的圆脑袋了。综合考虑下选择了叹息之墙99a(小号手)。方形的脑壳便于安装设备,同时小号手内部空间大的优势体现得淋漓尽致。
底盘:
底盘采用一块stm32c8t6作为主控,两个100rpm的n20减速电机作为主要动力源,一块DRV8833作为pwm调速芯片。采用7.4v降压6.5v为电机供电。(测试极速大约5cm/s,原地转圈速度约90度/秒。秒爬坡性能还可以,就是履带会打滑,后续考虑打印一些软片制作挂胶履带。 )
底盘设计
2.1 目标功能:
通过安装在炮塔上的esp32cam作为上位机,接收手机端发送的控制信号,向安装在底盘上的c8t6发送串口控制信号,实现对 车体行动;炮塔转动;灯光开关 等动作的控制。
2.2 车体基本功能
首先对底盘内部空间进行建模,数据可以略微小于底盘内部实际宽度,这一步是为了方便后续设计以及购买模块的时候经行空间管理:
底盘粗略建模:
部分原理图:
本来想找一块与l298n功能相似的模块。奈何实在是找不到,无奈之下采用了DRV8833与两块数字电路芯片自行制作了l2980相关功能。这样就能节省pwm波输出引脚,为后续增加舵机实现前倾,后倾等动作预留了io接口。
pwm波驱动下的DVR8833芯片输出的电压驱动两组N20电机,全速运转下没有明显发热,组装完成后发现,车体扭矩虽然满足要求,但是极速性能非常差,由于这是一个鱼和熊掌不可兼得的问题,要改进可能要提高整体输入电压。
2.3 炮塔的ESP32与底盘的c8t6通信
stm32的一路pwm输出接到了炮塔座圈下的360度舵机上,输出转速0到11度每秒。由于实现的功能中包含火炮的双向稳定功能,炮塔的转速必须与陀螺仪输出的角速度数据形成闭环控制。底盘的主板上预留了一组8pin段子,用于实现与炮塔的信息交互。
其中,VCC|GND端口连接5v供电网络,为整车的所有芯片供电,注意每个soc的输入端必须连接一个电容,以缓解电机、舵机等启动时发生的电压跳变,保护soc。两组pwm控制信号连接到炮塔的高低机,开火模拟舵机控制端,R/TX_gyro连接炮塔上的陀螺仪芯片,这是炮塔双稳pid系统的关键组件,当然,双稳作为可选功能,这里可以不接(陀螺仪建议远离电机)。
利用PID算法,在陀螺仪的加速度数据与炮塔电机转速之间建立闭环控制,就可以实现炮塔水平方向的类云台效果:
底盘添加了灯光功能后,总装效果如图:
炮塔
炮塔的设计是最难的,由于我不是机械设计相关专业,火炮的结构配合出现了非常大的设计困难,在大约20版废案后总算解决了模型运动中发生相干等运动配合难题。现阶段火炮的控制采用连杆方案,导致控制精度非常低,高低机稳定很差。下一步考虑改用齿轮配合,增大运动精度。
通过串口信息来进行控制
完成pwm波输出后,就可以让电机转起来了,由于DRV8833的真值表是
1/pwm | 0 | 正转 |
0 | 1/pwm | 反转 |
0 | 0 | 停止(电磁感应刹车) |
通过普通io口和cd4066来交换pwm波的输出线路,另一路就会被自动下拉到0。此时方向已经可以控制了,接下来就要将pwm占空比信息与串口输入信息关联起来。
4.1 底盘主板(c8t6):
相较于V1版本,我加了20块钱换装了更小的核心板,因为要预留方向机电机的控件,V1版本主板会导致空间逼仄,难以安装电池。
c8t6的相关配置文件都能找到大量例程,这里就不再赘述,仅展示主函数代码。
c8t6主函数:
int main(void)
{
int fir = 110;
/*定时器与时钟*/
GENERAL_TIM_Init();
ctrl_init();
/*ADC电压检测*/
AD_Init();
/* LED 端口初始化 */
LED_GPIO_Config();LED0_OFF;LED1_OFF;LED2_OFF;
/*方向机初始化*/
DIR_MOTOR_Init();
TIM4_PWM_Init(1999,719);//1750<a<1950
/*pwm波发生器*/
PWM_TIM_Init();
delay_ms(100);//等待上位机开机,可以改成上位机发送开机信号,这里偷个懒。
/* 上位机串口初始化 */
USART_Config();
/* 陀螺仪串口初始化 */
USART2_Config();
/*pid计算初始化*/
PID_param_init();
SYS_ONLINE();
首先判断电池电压是否充足,过放会对电池造成巨大损害,后续可能考虑在硬件上加以限制,这里采用额定7.4V动力电池,主板的电压区间由选择的DC降压模块和电调模块共同决定。
while (CTRL.Voltage>=7.5)
{
if(Cnt_10 == 10000){
CTRL.Voltage = Get_Voltage();//电压读取
Cnt_10 = 0;
}else{
Cnt_10++;
}
灯光控制与电机控制:
//灯光控制
if(CTR->LED_mod==1){
int dis = 0;
LED0_ON;
dis = CTRL.speed_L - CTRL.speed_R;
if(dis>=30){
LED_Flash(2);
}else if(dis<=-30){
LED_Flash(1);
}else{LED1_OFF;LED2_OFF;}
}else{
LED0_OFF;LED1_OFF;LED2_OFF;
}
//速度控制
SET_SPEED_1(CTRL.speed_L);
SET_SPEED_2(CTRL.speed_R);
解算炮塔控制信号:
//炮塔控制
if(!CTRL.if_adjust){//判断是否开启双稳
Once = 1;
CTRL.tmp_angle=Gyroscope[2];
switch(CTRL.turn){
case 0:
TIM_SetCompare1(TIM4,1850);//停止
break;
case 1:
TIM_SetCompare1(TIM4,1870);//顺时针
break;
case 2:
TIM_SetCompare1(TIM4,1830);//逆时针
break;
case 3:
if(CTRL.altitude>=90){CTRL.altitude--;delay_ms(15);}//主炮升高
break;
case 4:
if(CTRL.altitude<=120){CTRL.altitude++;delay_ms(15);}//主炮下降
break;
}
TIM_SetCompare1(TIM3,CTRL.altitude);
双稳:
float pd = 0;
//float dt = 0;
pd = CTRL.altitude-CTRL.alt_pid;//高低机陀螺仪数据
if(pd>=120){//限制高低机角度,防止主炮把车体撅了
pd = 120;
}else if(pd<=90){
pd = 90;
}
//dt = time_period_fun(Gyroscope[2]-CTRL.tmp_angle);
TIM_SetCompare1(TIM3,pd);//输入主炮高低信号,这里采用开环比例控制
CTR->pid_return = time_period_fun(Gyroscope[2]-CTR->tmp_angle);//PID计算
TIM_SetCompare1(TIM4,CTRL.turn_pid-CTRL.pid_return);//输入方向机PID控制数据
}
4.2 PID实现方向机控制 :
PID实现部分在附录2、3中,每台系统的PID参数都不尽相同,需要仔细调节,调节过程非常痛苦,还望看到这里的读者大佬们提出宝贵的建议。
4.3 上位机(esp32cam):
前端界面直接可以使用html制作,esp32cam的html前端界面有非常多的例子可以参考这里我直接采用了一位大佬的代码,使用websocket控制esp32cam发送信息,引用这位大佬的文章 :引用:(34条消息) 基于esp32-cam的监控小车_待在图书馆的毛毛虫的博客-CSDN博客_esp32小车
代码功能为使用websocket向esp32cam输出控制信号,同时esp32cam向网页输出视频信号