毕业设计--球上自平衡机器人

目录

前言

一、机器人原理分析

二、控制器设计

三、程序部分

四、硬件清单

五、电路设计

六、结构设计

七、总结与展望

总结

展望


2021 8.18更新:

看到评论区很多人对这个机器人比较感兴趣,把之前挖好的坑填一下。

这次的主程序更新部分加入了ADRC自抗扰算法部分,一部分直接加入无名飞控的无人机自抗扰文件,另一部分是直接在control.c文件中写的。实际并没有使用ADRC算法。


这次把结构设计及PCB设计全部放在Github上了。有些小伙伴可能github用的还不是太熟练。在这里给大家推荐一些github快速上手的教程。

github使用基本教程

GitHub 和 GitHubDesktop 的使用步骤!!!_houyingshang的博客-CSDN博客_githubdesktop

GitHub分支创建及合并_阳阳丶Sheep的博客-CSDN博客_github创建分支 (与他人协作时经常用到分支功能,这里是分支的创建与合并)

github廖雪峰版完整教程

Git教程 - 廖雪峰的官方网站

最近github连接不太稳定,经常被墙,多进几次或者换个时间段就能进去了。

本次更新内容:

1.结构设计

在SolidWorks软件中完成的全部结构设计,包括3D打印件的模型文件。

2.论文文档

这里存放的是设计过程中参考过的论文。

同时分享一些网页文档: 链接:http://note.youdao.com/noteshare?id=8483919cd10c184ade674151b171b6c4

3.程序设计

参考过的球平衡机器人源码及各种相关传感器源码。由于Github限制单次上传不可超过100个文件,于是全部压缩。

4.电路设计

立创EDA软件导出的PCB设计原理图及电路图,导出为AD格式。由于我是使用立创EDA软件设计的,文件保存云端,本地只有打板的文件,于是使用导出功能导出成AD默认格式。


前言

本次毕业设计过程中,受到过许多人的帮助,收获良多,在此将机器人整体开源,同时总结一下机器人搭建过程中遇到的坑和未来的改进方向。

一、机器人原理分析

首先来看成品图

如图所示,该机器人根据陀螺仪的位姿数据,通过三全向轮驱动底部球体调整自己在球上的位置,保持动态平衡的同时实现全向移动。


保持动态平衡过程需要对机器人进行运动学分析,这里参考了平衡小车之家的运动学方程

自平衡控制问题转化为了输入:X、Y角度—控制器计算—输出:A、B、C电机转速的控制模型。


二、控制器设计

首先考虑参考平衡车控制,球上自平衡机器人本质上依然是一个一阶倒立摆问题。

这里参考了飞思卡尔直立车的控制方法,采用串级PID控制器,外环PD角度环,内环速度PI环。


由于我的驱动方案选择的是42步进电机,在速度闭环的时候有些问题。正常的直流电机+编码器的控制方案可以通过编码器将轮子的真实速度计算出来,从而和控制器的理想转速作差,实现速度控制。

而我这里的速度闭环是通过计算上一个时钟周期时给步进电机的控制量,通过运动学方程分解,得到机器人的虚拟速度,与理想转速作差控制。我认为这种速度闭环方式还是存在一定缺陷的,但是在网上查看论文的时候我发现有很多自平衡机器人都是用42步进电机来实现速度闭环的,不知道是什么方法。


这里还可以好好思考一下为什么角度环要用PD控制,速度环要PI控制,角度环的P部分和D部分对机器人控制有什么影响?在很多CSDN调试平衡车的博客中都有解释,这里就留给大家思考了。

三、程序部分

普通地在keil 5中开发STM32。

控制程序采用定时器0.5ms定时中断的方式进行计算,每触发两次中断计算对电机控制一次,这里还是推荐大家采用外部中断读取GY-521上的INT引脚的方式,控制计算周期。GY-521上的INT引脚每5ms触发一次跳变,采用外部中断的方式可以严格保证读取位姿数据与计算处理同步。

int TIM1_UP_IRQHandler (void)                
{
    u8 key_cal;
    if(TIM_GetITStatus(TIM1,TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIM1,TIM_IT_Update); 
        flag_target=!flag_target;
        key_cal=KEY_Scan(0);
        if(state_flag==1)//矫正结束
        {
            if(flag_target==1)//每读取两次陀螺仪控制一次 
            {
                        Read_DMP();                      //===读取倾角
                        scope();
                        return 0;
            }
        }
        if(key_cal==1)//矫正按键
        {
                        Angle_Zero_X=Angle_Balance_X;
                        Angle_Zero_Y=Angle_Balance_Y;
                        key_cal=0;
                  Flag_Stop=0;
        }
        if(key_cal==2||key_cal==3)//矫正按键
        {
        Flag_Stop=1;//关闭速度环I积分
        key_cal=0;
        }
        Angle_Bias_X =Angle_Balance_X-Angle_Zero_X;     //获取Y方向的偏差
        Angle_Bias_Y =Angle_Balance_Y-Angle_Zero_Y;     //获取Y方向的偏差
        if(control_mode==0)//PID控制模式
        {
        Encoder_Analysis(Motor_A,Motor_B,Motor_C);  //正运动学分析,得到X Y方向的速度
        Balance_Pwm_X= balance_X(Angle_Bias_X,Gyro_Balance_X);//X方向的倾角控制
        Balance_Pwm_Y=-balance_Y(Angle_Bias_Y,Gyro_Balance_Y);  //Y方向的倾角控制
//      if(++flag_target_2==4)//速度环频率慢于加速度环 但是还没加速度环 
//          {
            Velocity_Pwm_X=velocity_X(compute_X);      //X方向的速度控制
            Velocity_Pwm_Y=velocity_Y(compute_Y);     //Y方向的速度控制  
//          flag_target_2=0;
//          }
            Move_X =Balance_Pwm_X+Velocity_Pwm_X;   //===X方向控制量累加   
            Move_Y =Balance_Pwm_Y+Velocity_Pwm_Y;   //===Y方向控制量累加   
            Move_Z=0;                
            Kinematic_Analysis(Move_X,Move_Y,Move_Z);//逆运动学分析得到ABC电机控制量
        }
            Motor_A=Target_A;//直接调节PWM频率 
            Motor_B=Target_B;//直接调节PWM
            Motor_C=Target_C;//直接调节PWM
//以下都是为了速度连续化处理防止突变
            if(Motor_A==0)  Motor_A=motor_a_last;
            if(Motor_B==0)  Motor_B=motor_b_last;
            if(Motor_C==0)  Motor_C=motor_c_last;
            Xianfu_Pwm(2000);
            Set_Pwm(Motor_A,Motor_B,Motor_C);
            Gyro_Balance_X_last=Gyro_Balance_X;
            Gyro_Balance_Y_last=Gyro_Balance_Y;
            Gyro_Balance_Z_last=Gyro_Balance_Z;
            Angle_Balance_X_last=Angle_Balance_X;
            Angle_Balance_Y_last=Angle_Balance_Y;
            Angle_Balance_Z_last=Angle_Balance_Z;
            motor_a_last=Motor_A;
            motor_b_last=Motor_B;
            motor_c_last=Motor_C;
    }
      return 0;
}

对于电机控制,由于采用的驱动方案是步进电机,调速的方式是改变驱动步进电机的脉冲频率。我这里选择了三个定时器,动态调节定时器的频率,具体方式是在初始化时设定好定时器的预分频系数psc的值,然后在程序里动态更改ARR寄存器的值,从而改变定时器的定时频率。

//这里以A电机的速度控制为例 输入为 电机方向和电机速度
void set_motorA_speed(u8 dir,u16 speed)
{
    u32 arr;
    arr=speed;
        TIM_ARRPreloadConfig(TIM3,DISABLE);
        TIM3->ARR=arr;//计数到10000在归零重新计数
        TIM3->CCR4=arr/2;//保持占空比为50%
        TIM_ARRPreloadConfig(TIM3,ENABLE);
        TIM_Cmd(TIM3,ENABLE);
    if(dir==0)
    {
    GPIO_SetBits(GPIOA,GPIO_Pin_1);
    }
  else
  {
    GPIO_ResetBits(GPIOA,GPIO_Pin_1);
  }
}

小车的运动学分解代码实现如下,参考了平衡小车之家的代码:

/**************************************************************************
函数功能:小车运动数学模型
入口参数:X Y Z 三轴速度或者位置
返回  值:无
**************************************************************************/
void Kinematic_Analysis(float Vx,float Vy,float Vz)
{
	      Target_A   = Vx + L_PARAMETER*Vz;
        Target_B   = -X_PARAMETER*Vx + Y_PARAMETER*Vy + L_PARAMETER*Vz;
	      Target_C   = -X_PARAMETER*Vx - Y_PARAMETER*Vy + L_PARAMETER*Vz;
}
/**************************************************************************
函数功能:小车运动 正运动学分析 
入口参数:A B C三个电机的速度
返回  值:无
**************************************************************************/
void Encoder_Analysis(float Va,float Vb,float Vc)
{
		compute_X=(Va*2-Vb-Vc);
		compute_Y=((Vb-Vc)*sqrt(3));
		compute_Z=(Va+Vb+Vc);  
}

其余代码不全放出,具体可转到https://github.com/1812598631/graduate-design查看


四、硬件清单

材料价格数量淘宝链接
56mm全向轮45元/个3https://m.tb.cn/h.4vYp4EC?sm=77a719
42步进电机25/个3https://m.tb.cn/h.4wpMzLY?sm=eeba97
42步进闭环模块59.8元/个3https://m.tb.cn/h.4EuBpGe?sm=bb691b
LM2596S降压模块20元1https://detail.tmall.com/item.htm?id=41307963557
STM32F103C8T6-4飞控板59.8元1https://detail.tmall.com/item.htm?id=615978870514
GY-521六轴陀螺仪25元1https://m.tb.cn/h.4vYn0xG?sm=c94d34

用到的模块大致如上所示,C8T6的价格随着最近芯片涨价直线上升,我白嫖了实验室的两块板子,现在买一块实在太贵,可以等芯片价格稳定一些再买。其余开关排针等常见元件不再赘述。

五、电路设计

使用立创EDA软件进行设计

原理图如下所示:

PCB走线与原理图设计打包放在GITHUB中了

六、结构设计

使用solidworks设计整体结构,底板可在淘宝定制6050太空铝切割,蓝色件为正常3D打印件。

七、总结与展望

总结


球上自平衡机器人可以作为算法试验平台, 输入输出固定,更换不同控制器,将数据导入MATLAB进行分析即可比较控制器性能。

展望


结构部分

个人认为结构有两个改进方向,一方面参考以下论文:

余义. 单球驱动自平衡机器人位姿解算与控制系统研究[D].武汉科技大学,2019.

论文中采用的四足式驱动结构更有利于机器人自平衡控制。

一方面可以增加球体和机器人固定装置,利用机械结构将机器人与底部驱动球结合成一个整体防止机器人跳轮等问题。同时驱动球对于机器人平衡的影响较大,最好还是定制空心钢球,然后喷漆增大摩擦力,最有利于机器人自平衡控制。

控制部分

首先是控制原理,本文是针对建立好的运动学方程进行分析,通过串级PID算法来实现自平衡运动。该机器人的控制问题本质上是一阶倒立摆问题,可以采用动力学建模的方式,通过动力学分析算出平衡需要的虚拟力矩,再对电机进行力矩控制。

其次是控制器,PID控制算法应用广泛但也有一定的缺点,可以考虑采用模糊PID,ADRC自抗扰控制器,强化学习等智能控制算法对机器人自平衡进行控制。

整体工程文件:https://github.com/1812598631/graduate-design

主要参考论文

[1]余义. 单球驱动自平衡机器人位姿解算与控制系统研究[D].武汉科技大学,2019.

[2]刘桐. 基于三全向轮驱动的球轮自平衡机器人的研究与实现[D].北京工业大学,2018.

[3]韩京清.从PID技术到“自抗扰控制”技术[J].控制工程,2002(03):13-18.

  • 31
    点赞
  • 160
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
主程序: #include "sys.h" u8 Flag_Left,Flag_Right; // u8 Flag_Stop=1,Flag_Zero=0,Flag_Show,Flag_Qian,Flag_Hou,Flag_Left,Flag_Right,Flag_OK; //停止标志位和 显示标志位 默认停止 显示打开 float Motor_X,Motor_Y,Motor_Z; long int Motor_A,Motor_B,Motor_C; //电机PWM变量 long int Target_A,Target_B,Target_C; //电机目标值 int Voltage; //电池电压采样相关的变量 float Show_Data1,Show_Data2,Show_Data3,Show_Data4; //全局显示变量,用于显示需要查看的数据 u8 delay_50,delay_flag; //延时相关变量 u8 PID_Send; //CAN和串口控制相关变量 float Pitch,Roll,Yaw,Move_X,Move_Y,Move_Z,Roll_Bias,Pitch_Bias,Roll_Zero,Pitch_Zero; float Balance_Kp=200,Balance_Kd=19,Velocity_Kp=55,Velocity_Ki=10; //位置控制PID参数 int main(void) { Stm32_Clock_Init(9); //=====系统时钟设置 delay_init(72); //=====延时初始化 JTAG_Set(JTAG_SWD_DISABLE); //=====关闭JTAG接口 JTAG_Set(SWD_ENABLE); //=====打开SWD接口 可以利用主板的SWD接口调试 LED_Init(); //=====初始化与 LED 连接的硬件接口 KEY_Init(); //=====按键初始化 OLED_Init(); //=====OLED初始化 uart_init(72,128000); //=====串口1初始化 uart2_init(36,9600); //=====串口2初始化 uart3_init(36,115200); //=====串口3初始化 Adc_Init(); //=====adc初始化 IIC_Init(); //=====IIC初始化 delay_ms(50); MPU6050_initialize(); //=====MPU6050初始化 DMP_Init(); //=====初始化DMP delay_ms(500); //=====延时等待初始化稳定 EXTI_Init(); //=====MPU6050 5ms定时中断初始化 CAN1_Mode_Init(1,2,3,6,0); //=====CAN初始化 MiniBalance_PWM_Init(7199,14); //=====初始化PWM 用于驱动电机 while(1) { if(Flag_Show==0) { DataScope(); //===上位机 delay_flag=1; //===50ms中断精准延时标志位 oled_show(); //===显示屏打开 while(delay_flag); //===50ms中断精准延时 主要是波形显示上位机需要严格的50ms传输周期 } else { APP_Show(); //===APP oled_show(); //===显示屏打开 delay_flag=
源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用。源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可。源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用。源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可。源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用。源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可。源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用。源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可。源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用。源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可。源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用。源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可。源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用。源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可。源码是经过本地编译可运行的,下载完成之后配置相应环境即可使用。源码功能都是经过老师肯定的,都能满足要求,有需要放心下载即可。源码是经
机器人毕业设计是一个涉及机器人技术的设计项目。在这个设计中,目标是开发一个能够执行特定任务或具有特定功能的机器人。 首先,我们需要确定机器人的设计目的和功能。例如,它可以是一个自动化的清洁机器人,可以帮助保持室内环境干净和整洁。它可以具备机器视觉技术,能够识别和避开障碍物,并且能够有效地清扫室内的地面和角落。 其次,我们需要选择和集成适当的硬件和软件组件,以实现设计目标。如传感器、执行机构、控制系统等。对于清洁机器人,传感器可以用于检测和定位污垢,执行机构可以是清扫刷子和吸尘器,控制系统可以编程机器人进行清洁操作。 设计过程中,需要考虑机器人的动力和能源供应。我们可以选择使用电池或其他可持续能源来为机器人提供动力,并确保机器人在使用中能够持续工作一段时间。 另外,安全性也是设计中重要的考虑因素。机器人应该具备避免碰撞和损坏周围物体的能力,并且在发生故障或异常情况时能够及时停止运行。 最后,我们需要进行测试和优化,以确保机器人能够稳定和有效地执行其设计功能。这包括测试机器人在不同环境下的性能,通过实地测试识别和解决潜在问题,并改进机器人的设计。 总之,机器人毕业设计是一个涉及到机器人技术的综合性项目,要考虑到设计目的、功能、硬件和软件集成、动力和能源供应、安全性以及测试和优化等方面。通过这个设计项目,我们可以深入了解机器人技术的应用,同时提升自己的设计和实施能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值