智能车浅谈--软件布局篇

前言

智能车省赛已经过去将近一个月,为了纪念一个多学期的努力,在此做一个小总结。

软件上的结构布局

(基于C车模说明,其他车模也可做参考)

        1:x路ADC读取。(针对电感) 

                读出来的值,最好做个滤波处理,bz这里用的均值滤波。

参考代码(主控WCH32V307,用的龙邱商家的库):

    /*电感 ADC读取初始化*/
    ADC1Init(ADC1ch12_C2);    
    ADC1Init(ADC1ch13_C3);
    ADC1Init(ADC1ch14_C4);

    /*电感读取 10次数据取均值*/
    ADC[0] = ADC1_Read_Average(ADC1ch12_C2,10); //左1
    ADC[1] = ADC1_Read_Average(ADC1ch13_C3,10); //中间
    ADC[2] = ADC1_Read_Average(ADC1ch14_C4,10); //右1

              摄像头一帧数据裁剪,再通过大津法(也可是其他算法)获取阈值,最后二值化。(针对灰度摄像头,本章不细讲)

        2:一路IO口作PWM输出。

                        用来控制舵机打脚转向。

参考代码:

    /*舵机信号线IO口初始化PWM模式 频率50HZ */
    ServoInit(50);   

    /*pwm控制 当前输出对应舵机中值*/   
    ServoCtrl(Servo_Center_Mid);  

注:舵机中值需要自己用按键一点点控制pwm输出找到,同时找到左打脚极限和右打脚极限的值,根据这个值做好限幅处理,这样就不会使舵机转到极限位置卡齿轮从而损坏舵机。

        3:倆路IO口作PWM输出,倆路IO口作高低电平输出。

                        用来通过电机驱动模块间接控制电机转动

                        注:有的电机驱动模块是需要4路IO口输出PWM进而控制电机转动。

参考代码:

    /* 电机驱动的频率为10Khz */
    MotorInit(10000); 
    
    /*双电机控制*/
    MotorCtrl(dutyL, dutyR);   

        4.定时器输入捕获模式,获取编码器的一定时间内的脉冲数,进而获取当前电机转速

(这个配置一般商家给的例程会有,不需要自己配置)

参考代码:

    /*编码器模式初始化*/
    Encoder_Init(TIM2_ENCA_A15,TIM2_ENCB_B3);  
    Encoder_Init(TIM3_ENCA_B4, TIM3_ENCB_B5);  

基于以上四点,软件上的基本配置就好了。布局完成后,现在谈谈让车跑起来的思路。

软件上的编程思路:

        1.舵机转向环:

        电感相当于车的眼睛,比如车前瞻架倆路电感,一左一右对称。通过电磁感应(赛道上有铺设电磁线)和ADC通道读取获得俩个感应电压Lv(左电感产生的感应电压),Rv(右电感产生的感应电压)。具体原理参考这里:传送门

       理论上小车放在赛道正中间,Lv ≈Rv

        小车水平向左移动(至右电感垂直投影在赛道正中间),Lv < Rv

        小车水平向右移动(至左电感垂直投影在赛道正中间),Lv > Rv

       获取的值有了这种关系,我们就可以利用俩个电感值(感应电压值)作差,得到一个偏差值Error。

                     Error = Lv – Rv;(当然还能用差比和,归一化等使算出来的Error值更稳定)

       将这个error乘以一定比例kp加在舵机中值上,最终算出来的值就是要给到舵机的pwm。这样,小车就能正常寻迹了。(后期想要优化寻迹,可能就需要PID,模糊控制等其它算法了)

参考代码:

    /*************************电磁的舵机打角PID*************************/

    //差比和 分母加上中间电感产生的稳定效果相对较好
    dainci_piancha = 100*(ADC[0] - ADC[2])/(ADC[0] + ADC[2] +ADC[1]);  
    //舵机的偏差PID
    jiao= (dianci_P*dainci_piancha + dianci_D * (dainci_piancha - Last_dainci_piancha));
    Last_dainci_piancha = dainci_piancha;
    DUOJI_PWM=(u16)(Servo_Center_Mid+jiao);
    ServoCtrl(DUOJI_PWM);     // 舵机PWM输出,转向

        2.电机开环

        电机的速度无非是主控输出倆路PWM给到电机驱动,再驱动电机转动。 我最开始让小车跑的时候就是给一个固定的PWM,也就是全程跑一个速度,这个属于开环控制。开环控制有一定的缺陷,比如不能让小车在直道上跑相对更快的速度,速度快了弯道和各类元素可能走不好,停车也是用惯性停的。总结来说,开环跑速度上不去。

        3.电机闭环(速度环)

        闭环利用编码器传回来的脉冲数,计算出实时速度(bz这里是直接用的脉冲数来当做速度与自己的预期作PID)。

    ECPULSE1 = Read_Encoder(TIM3); //左电机  获取脉冲值(间接的速度值)
    ECPULSE2 = Read_Encoder(TIM2); //右电机  获取脉冲值

         与我们的预期速度作差算出一个速度偏差error值,然后作PID。算出一个新的PWM输出到电机上。举个例子:比如实际速度小于我的预期速度,那说明小车速度没达到我的预期,那么就要基于当前速度再加速。理论上通过PID运算,最后我输出的PWM就会比当前的PWM值要大。电机速度环调的差不多的时候,赛道不同的路段跑不同的预期速度就好写了。

        参考代码:

        /*************   电机增量式PID控制  ***************/
        S_error=(int)(speed-Current_speed); //speed为我的预期速度,Current_speed为算出来的当前速度
        duty=duty+(S_error-S_error_pre)*Motor_P+S_error*Motor_I + Motor_D*(S_error - 2*S_error_pre + S_error_prepre);
        S_error_prepre = S_error_pre;
        S_error_pre=S_error;

        Car_control_dianji();  //PWM输出duty值 作用到电机上

      上面代码通过PID算出来的PWM,在输出到电机前可以做一个限幅,因为如果PID参数没有调好导致超调情况,小车电机可能会疯转,所以为了保护好自己的爱车,没调好前可以限个幅。(如下)

        /*************   电机增量式PID控制  ***************/
        S_error=(int)(speed-Current_speed);
        duty=duty+(S_error-S_error_pre)*Motor_P+S_error*Motor_I + Motor_D*(S_error - 2*S_error_pre + S_error_prepre);
        S_error_prepre = S_error_pre;
        S_error_pre=S_error;

        if(duty>=4500) duty=4500;    //限幅值要自己设置
        else if(duty<=-4500) duty=-4500;
        Car_control_dianji();  //PWM输出duty值 作用到电机上

       注:电机的闭环可以每个电机单独写一个闭环,也可以把获取的左右编码器的脉冲值取平均,然后只写一个闭环。(个人建议写每个电机单独写,若你是B车模当我没说doge。因为单独写好写差速

         调速度环要注意的点:

        一定要让主控能够区分电机的正反转。编码器有个dir脚是用来区分正反转的,比如正转输出高电平,则反转就是低电平。在代码上写个判断即可。(由于大伙编码器的装法大概率是镜像分布在左右,若基于上述条件,如果左编码器正转为1,反转为0。则右编码器正转为0,反转为1。这个自己试试就知道了,因为对于编码器本身只识别是顺时针转还是逆时针转。若顺时针转输出1,则逆时针转肯定输出为0。)参考如下:

    /*令正转数值为正数,反转数值为负数*/
    /*若正转数值读出来的数值为负,则通过代码修正为正数。反之一样*/
    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5) == 1) //满足说明为正转
    {
        if(ECPULSE1 < 0)
        {
            ECPULSE1 = -ECPULSE1;
        }
        else
        {
            ECPULSE1 = ECPULSE1 * 1;
        }
    }
    else //不满足说明为反转
    {
        if(ECPULSE1 < 0)
        {
            ECPULSE1 = ECPULSE1 * 1;
        }
        else
        {
            ECPULSE1 = -ECPULSE1;
        }
    }
    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_3) == 1)//满足说明为反转
    {
        if(ECPULSE2 < 0)
        {
            ECPULSE2 = ECPULSE2 * 1;
        }
        else
        {
            ECPULSE2 = -ECPULSE2;
        }
    }
    else//不满足说明为正转
    {
        if(ECPULSE2 < 0)
        {
            ECPULSE2 = -ECPULSE2;
        }
        else
        {
            ECPULSE2 = ECPULSE2 * 1;
        }
    }

        4.电机闭环(方向环)

        如果说电机速度环是为了控速,那么电机方向环就是用来辅助小车转向。你可以想想F车(三轮)是怎么寻迹的,没有舵机的F车只能通过电机差速(俩个轮子转速不同)来转向。但有舵机的C车模同样可以过弯道利用差速辅助舵机,从而使小车弯道速度更快通过。(弯道快才是真的快,谁直道不会加速?(doge))。如何写方向环这里就提供一个思路,因为是弯道差速,可以参考舵机转向的PID。

最后给各位第一次准备智能车的软件手一些建议:

1.电机速度环和电机方向环不能重叠,代码上要理清楚

2.PID控制最好写在定时器里

3.能写结构体就写结构体,不然后面变量多的怀疑当初是不是自己加的。

4.模块化编程不用多说了吧,然后就是写注释。

如果想了解小车的硬件布局,可以参考这篇文章--智能车浅谈——硬件篇

以上就是bz对软件上的思路和布局,希望能对您有所帮助,如果有写错的地方望指正。

  • 14
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 平衡小车是一个非常有趣和富有挑战的控制系统,它主要通过对小车的力和角度进行控制来实现平衡。尤其在小车快速转弯时,转向环KD的设置显得尤为重要。 首先,我们需要了解转向环KD的定义。在控制系统中,转向环KD是一种控制参数,可以帮助我们调节转向时小车的响应时间和平滑程度。这个参数通常包含两个单独的控制参数,即比例常数KDp和微分常数KDd。比例控制参数KDp通常用来控制小车的单位时间响应,而微分控制参数KDd用于控制小车响应的平滑度。 在小车快速转弯时,设置适当的转向环KD参数非常重要。如果KDp设置过高,小车将会响应过度,并产生不必要的震荡。相反,如果设置太低,小车的响应时间将过长,使得转向过程不够平滑。相反,如果KDd设置过高,小车会产生过多的振荡,会影响平衡性和稳定性。因此,我们需要在实践中逐步调整这些参数,以找到最佳的设置。 总体来说,平衡小车转向环KD设置的重要性不容忽视。只有找到正确的KD参数设置,小车才能在转向时保持平衡性和稳定性,并且获得良好的响应速度和平滑性。因此,在控制小车时,我们必须注意这些参数的设置,并根据实际情况进行逐步调整。 ### 回答2: 平衡小车是一种控制系统的研究案例,这种小车的核心任务就是保持平衡。平衡小车通常采用PID控制器,并在PID控制器的基础上增加转向控制器,以实现在一定速度和路面状况下的平衡和转向稳定。其中,kd参数是控制器中的一个重要参数,用于调整转向控制器的反馈增益,以达到良好的转向控制效果。 首先,kd值的设置需要考虑平衡小车的速度和路面状况。当小车在平整路面上行驶时,kd值应适当增加,以增强转向控制器的响应速度,减少小车的摆动幅度。此外,当小车的速度较快时,kd值也应适当增加,以保证小车在高速转向时的稳定性。 其次,kd值的设置还需要考虑小车的负载以及电池电压等因素。负载过重会影响小车的平衡能力,因此,在设置kd值时需要考虑负载的重量,并增加kd值以提高小车的稳定性。同时,小车电池电压不足也会影响kd值的设置,建议在设置之前应该先充好电,以保证控制器的反馈效果。 综上所述,平衡小车的kd值设置需要综合考虑多种因素,并进行适当的调整,以在不同的路况和负载情况下保持良好的转向控制效果。 ### 回答3: 平衡小车转向环KD的设置是建立在PID控制算法基础之上的。KD是控制系统中的微分常数,它用来控制系统的动态响应特性。设置KD的目的是让小车摆动后迅速稳定下来,并尽量避免摇晃。 小车的转向控制可以使用PD控制系统,其中P代表比例常数,D代表微分常数。在PD控制系统中,P是用于控制小车响应速度的主要参数,D则用于抵消小车运动时的摆动。因此,合理的KD设置可以很好地平衡这两个参数的作用。 KD的设置需要根据小车的实际运动情况来进行。如果KD设置过高,则小车可能在行驶过程中出现抖动或者进一步失控。如果KD设置过低,则小车的稳定性可能会下降,不能快速控制摆动。通常,建议先设置较小的KD,并根据实际测试结果逐渐增加,直到小车的稳定性达到理想状态为止。 除了KD设置之外,还应注意小车其他相关参数的调整,例如小车重心、轮距等。这些都将对小车的稳定性产生影响。在调整这些参数时,应尽量避免对KD设置造成负面影响。最终,通过合理的KD设置和其他参数的优化调整,可以获得较好的转向控制效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值