下图是大致的硬件连接方式(从另外一个视频借用)

零件清单

  • Arduino Pro Micro  timer1和timer3,都是16位的计数器。
  • 2个 NEMA 14步进电机(每步1.8度)
  • 2个 模型飞机轮毂,轮毂从4毫米到5毫米钻孔并压配到电机轴上
  • 2个 步进电机驱动模块
  • MPU-6050陀螺仪/加速度计
  • 3节LiPo电池
  • 蜂鸣器
  • LED和几个电阻。
  • 一些针头和插座,一些电线和一些热缩管
  • 大约20个M3 16 mm螺钉(带螺母)
  • 两个用于选择功能的拨动开关

========================================================================

信息来源 from :

Mini balancing robot | Axel's DIY page

https://www.youtube.com/watch?v=egfLymeuGhg

Arduino | Axel's DIY page

Arduino Mega Balancing Robot | Axel's DIY page

Balancing robot with Raspberry Pi | Axel's DIY page

========================================================================

控制理论 PID的通俗解释

  • I 对过去情况的记忆
  • P 对现在情况的反应
  • D 对未来情况的预测

P 、I 、D 之间的关系

  • D积分后是P,P积分后是I。 反过来,I微分后是P,P微分后是D。
  • 类似加速度积分后速度,速度积分后是位置。反过来,位置微分后是速度,速度微分后是加速度。

========================================================================

普通的平衡机器人,使用了两个嵌套的PID控制器进行控制。

  • 外层PID控制器 ,将电机速度和设定速度之间的差值作为输入,计算出角度(加速度)喂给内层PID。外层回路不需要D部分。外层的积分是位置。主循环(外层PID)400Hz的频率。
  • 内层PID控制器 ,获取所需角度和当前角度之间的差值并计算马达的速度。

========================================================================

此外,还有使用了3层PID控制器的平衡小车

外层是位置控制, 具有位置记忆能力,推离后回到原位

中层是速度控制

内层是角度控制(加速度)

========================================================================

系统调参:
一、先调整内层角度PID控制回路。
P部分先调试:将角度设置为0(机器人垂直向上),并将I和D增益设置为0.然后增加P增益直到出现振荡。
I和D部分后调试:然后稍微减少P增益并增加一些I和D增益。当正确完成时机器人应该能够平衡,但会漂移或者被推动。机器人在推动时应该快速地返回垂直状态,并且不应该有高速振荡、振动或大的超调。
二、再调整外层速度PID控制回路。
这通常容易得多,只需添加一些P和I增益并实验即可。

==========================================

数据读取

角度传感器,使用MPU-6050模块,不用MPU计算模块,从传感器读取原始数据,并自己进行传感器融合。陀螺仪和加速度计这两者的结合产生了良好且相对无噪声的角度估计,

  • 1、通过积分陀螺仪信号计算角度,“陀螺仪角度”有漂移,不是很准确,“
  • 2、然后根据使用加速度计数据计算的另一个角度值以及使用arctan函数的一些基本三角函数稍微调整该角度。加速度计角度”非常嘈杂,并且无法单独使用。

========================================================================

两个辅助开关

数字引脚14.开关用于在静止和前进之间切换,
数字引脚15.开关用于随机转身

========================================================================

arduino程序

当机器人感觉到它的角度接近0(垂直向上)时,机器人将开始平衡。
如果机器人感觉到设定点角度和当前角度之间的角度差太大或者当前角度变得太大(如果机器人在任何方向上倾斜),则平衡机器人将停止。
Arduino还监控电池电压,并在电压过低时停止机器人。
Arduino还监控状态开关,并根据选择开关状态设定机器人状态。

准备

    时间△t  周期时间 = 结束时间-开始时间

       开始时间

       结束时间

    角度 = 角度1+角度2

       角度1----直接角度读取

       角度2----间接角速度积分(陀螺仪)

计算

    外层PID

       计算P

       计算I

       计算D

targetAngle = speedPID.updatePID(targetSpeed, motorSpeed   , deltaTime) //从目标速度计算加速度

内层PID

       计算P

       计算I

       计算D

motorSpeed = -anglePID.updatePID(targetAngle, currentLeanAngle, deltaTime)//从目标加速度计算电流

输出

    轮子的定时器脉冲(是驱动电流脉冲,不是电机步进脉冲)

========================================================================

  1.  // 定义变量

//时间变量

long lastLoopTime = STD_LOOP_TIME;

long lastLoopUsedTime = 0;

unsigned long loopStartTime = 0;

float deltaTime = 0;  // unit: seconds

//传感器变量

Mpu6050 imu = Mpu6050(MPU6050_ADDRESS);                        //角度

ComplementaryFilter angleFilter;                               //互补( 互余) 过滤器

float voltage = 0;              // battery voltage

int randomTurnCounter = 0;      // used to make random turns   //机器人设置状态变量

// PID 变量

Pid anglePID(ANGLE_P, ANGLE_I, ANGLE_D, ANGLE_I_LIMIT);

Pid speedPID(SPEED_P, SPEED_I, SPEED_D, SPEED_I_LIMIT);

外层P  I

内层P  I  D

//状态变量

boolean balancing = false;

float currentLeanAngle = 0.0f;  // float type

float targetAngle

int8_t directionMotor1 = 0;

int8_t directionMotor2 = 0;

float targetSpeed = 0;          // drive and turn, unit: wheel revulutions per second轮子旋转频率

float turningSpeed = 0;        //  转弯速度--轮子差速

//输出

Buzzer buzzer = Buzzer(BUZZER_PIN); //蜂鸣器

float motorSpeed = 0;               // the actual forward/reverce speed of the motors.

=======================================================================

void setup() {

  1.  //子程序,timer1中断的定义,
  2.  //子程序,timer3中断的定义,电机转一个角度

===================================================================================

void loop() {

  1. // 读,机器人的控制(拨动开关)

void behaviour() {

targetSpeed = 0.5f;

turningSpeed = 0.1f * random(1, 5);

  1. // 读,惯性传感器
  1.     //读,时间, 计算主循环的使用时间,

lastLoopUsedTime = micros() - loopStartTime;    //总时间

if (lastLoopUsedTime < STD_LOOP_TIME)           //如果总时间不到设定值就延时

delayMicroseconds(STD_LOOP_TIME - lastLoopUsedTime);

lastLoopTime = micros() - loopStartTime;       //延时后的总时间

deltaTime = (float)lastLoopTime / (float)1000000;//从微秒到秒的转换

loopStartTime = micros();

  1.             // 计算, ----初始化状态,角度和速度,
  2.             // 当处于非平衡状态-->加电超过3000微秒-->机器人接近垂直状态-->平衡状态

if (!balancing && millis() > 3000  &&  abs(currentLeanAngle) < START_ANGLE_ERROR) {

    // 初始化机器人

balancing = true;

turningSpeed = 0

motorSpeed = 0;

anglePID.resetPID();

speedPID.resetPID();

buzzer.buzzBlocking(20);

}

  1.            //计算,处于平衡状态, 误差角(目标角度-当前角度)太大(最大误差设定值), 停机

if (balancing) {

// stop balancing if angle error is to large.

if ((targetAngle - MAX_ACCEPTABLE_ANGLE_ERROR) > currentLeanAngle ||

currentLeanAngle > (targetAngle + MAX_ACCEPTABLE_ANGLE_ERROR)) {

balancing = false;

buzzer.buzzBlocking(50);

}

  1.            //计算,处于平衡状态,倾角太大(最大允许设定值), 停机

// stop balancing if the robot is leaning to much in any direction.

if (-MAX_ACCEPTABLE_ANGLE > currentLeanAngle || currentLeanAngle > MAX_ACCEPTABLE_ANGLE) {

balancing = false;

buzzer.buzzBlocking(50);

}

  1. //计算,俯仰角度

float accAngle = atan2(imu.getAccelY(), imu.getAccelZ()) * 57;

//加速度传感器

// atan2() 函数,其返回值是-π—π,从π转换到度,要除以3.14,再乘以180,系数大约是57

currentLeanAngle = angleFilter.calculate(accAngle,imu.getGyroX(), deltaTime);

//用陀螺仪传感器做简单的互补矫正

  1. //计算,用PID计算俯仰角度(加速度)和速度

targetAngle = speedPID.updatePID(targetSpeed, motorSpeed   , deltaTime);

motorSpeed = -anglePID.updatePID(targetAngle, currentLeanAngle, deltaTime);

/*

atan 和 atan2 都是求反正切函数,如:有两个点 point(x1,y1), 和 point(x2,y2);

float angle = atan( (y2-y1)/(x2-x1) );

float angle = atan2( y2-y1, x2-x1 );

atan2 的优点在于 如果 x2-x1等于0 依然可以计算,但是atan函数就会导致程序出错;*/

  1.      //计算,电机速度,

         //输出,电机速度

   

float leftMotorSpeed =  (motorSpeed + turningSpeed) * 3600;

                     // motor speed is converted from 每秒几圈 to每秒几度

float rightMotorSpeed = (motorSpeed - turningSpeed) * 3600;

setMotorSpeed( leftMotorSpeed, 2);  //左电机--2

setMotorSpeed(rightMotorSpeed, 1);  //右电机--1

digitalWrite(STEPPER_ENABLE_PIN, LOW);         //enable the stepper motors

}

else

{

setMotorSpeed(0, 2);                           // set the speeds of each motor to zero

setMotorSpeed(0, 1);

digitalWrite(STEPPER_ENABLE_PIN, HIGH);        // disable the stepper motors

}

  1. // 读,  输入子程序的马达转速,

    // 计算,

    // 输出,电机方向,电机定时器(方波占比)directionMotorX和OCRXA

void setMotorSpeed(int16_t tspeed, int motorID)

{

long timer_period;

int16_t motorspeed = tspeed;

if (motorID == 1) {

if (motorspeed > 0) {

timer_period = 2000000 / motorspeed;         // 2Mhz timer

directionMotor1 = 1;

digitalWrite(STEPPER_1_DIR_PIN, LOW);

} else if (motorspeed < 0) {

timer_period = 2000000 / -motorspeed;

directionMotor1 = -1;

digitalWrite(STEPPER_1_DIR_PIN, HIGH);

} else {

timer_period = 65535;

directionMotor1 = 0;

}

if (timer_period > 65535)                       // Check for maximun period without overflow

timer_period = 65535;

OCR1A = timer_period;                            // OCR1A保留字 ,不需要声明

if (TCNT1 > OCR1A)                              // Check  if we need to reset the timer...

TCNT1 = 0;                                     // TCNT1 保留字 ,不需要声明

} else if (motorID == 2){

if (motorspeed > 0) {

timer_period = 2000000 / motorspeed;           // 2Mhz timer

directionMotor2 = 1;

digitalWrite(STEPPER_2_DIR_PIN, HIGH);

} else if (motorspeed < 0) {

timer_period = 2000000 / -motorspeed;

directionMotor2 = -1;

digitalWrite(STEPPER_2_DIR_PIN, LOW);

} else {

timer_period = 65535;

directionMotor2 = 0;

}

if (timer_period > 65535)                     // Check for maximun period without overflow

timer_period = 65535;

OCR3A = timer_period;

if (TCNT3 > OCR3A)                             // Check  if we need to reset the timer...

TCNT3 = 0;

}

}

============================================================

2轮平衡小车算法分析相关推荐

  1. 平衡小车c语言程序,【全部开源】两轮平衡小车(原理图、PCB、程序源码、BOM等)...

    同网上一般网友制作的平衡小车不一样,这个平衡小车最大的特点就是它的整体很小,PCB面积只有2.5cm*5.0cm,这个可能还没有网友制作的平衡小车的一个电机驱动板大,但是却已经实现了相同的功能.我在器 ...

  2. ps2摇杆模块控制小车_八个超赞的两轮平衡小车设计,小白最爱

    智能车种类众多,其中两轮平衡车特别受到了工程师的喜爱,整理了8个两轮平衡车的资料,一起看看这个小可爱吧. 1.基于ARM-STM32的两轮自平衡小车 小车直立和方向控制任务都是直接通过控制小车两个电机 ...

  3. 八个超赞的两轮平衡小车设计,小白最爱

    智能车种类众多,其中两轮平衡车特别受到了工程师的喜爱,整理了8个两轮平衡车的资料,一起看看这个小可爱吧. 1.基于ARM-STM32的两轮自平衡小车 小车直立和方向控制任务都是直接通过控制小车两个电机 ...

  4. 基于stm32c8t6的两轮平衡小车 第二篇——原理图及CubeMx配置

    目录 1.原理图 2.CubeMx配置 (1)创建工程 (2)配置时钟树 (3)仿真模式选择 (4)TIM2配置为PWM输出模式 (5)定时器TIM3,TIM4设置为编码器模式 (6)蓝牙串口配置 ( ...

  5. 基于RT-Thread的两轮平衡小车设计

    一.前言 最近参加了RT-Thread官方发起的RT-Robot Car DIY活动,借此机会想总结一些自己本科四年的所学的部分知识. 也可以帮助到那些需要的小伙伴(可以参考我的代码中对RT-Thre ...

  6. 毕业论文 | 基于STM32的双轮平衡小车设计(基于Keil5的完整注释版代码工程,原器件清单)

    博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 预告:代码及文档下载 其他参考代码 ...

  7. stm32两轮平衡小车项目详解

    摘要 这个项目是在20年11月初开始的,当时的我很迷茫,本应该去实习的我在线上培训,觉得无聊,便有了自己一人做项目的想法.也没想到这个项目做了将近整整一个月,才差不多做了出来.也是准备做两个项目的,这 ...

  8. 基于32单片机两轮平衡小车控制系统设计

    主控MCU采用STM32F103C8T6单片机,电机驱动模块采用TB6612FNG模块,姿态监测传感器采用MPU6050芯片,蓝牙模块采用HC-05蓝牙模块. 小车的运动分为直立环.速度环和转向环分别 ...

  9. 直立代码分析__两轮平衡小车原理

    本文依据网上资源整理而来,适用于初学直立车者. 一.原理 平衡小车是通过两个电机运动下实现小车不倒下直立行走的多功能智能小 车,在外力的推拉下,小车依然保持不倒下.这么一说可能还没有很直观的了解 究竟 ...

最新文章

  1. 前端学习 -- Css -- 伪元素
  2. [leedcode][JAVA][365][BFS]
  3. python建模大赛算法_Python数据分析kaggle-Titanic+天池-工业蒸汽量预测建模算法
  4. 618购物节要到了,Python帮你实现商品有货的微信提醒
  5. 一步一步学习Servlet中Request和Response
  6. java登录界面圆形头像_自定义圆形头像
  7. 服务器 设置 将 Tomcat 注册 到系统服务 及使用方法
  8. 如何使用本地账户完整安装 SharePoint Server
  9. 对Runtime的理解
  10. RHEL/Centos下VSFTPD服务器搭建
  11. OPPO设备设置第三方桌面为默认Launcher
  12. IT人,自我营销,你懂吗?
  13. Rust语言教程(1) - 一门没有GC的语言
  14. 前辈不是我,借他人事迹助暖通新人!
  15. 翻斗式雨量计的组成与工作原理
  16. “5G通达,AI赋能“ AI在网络规划中的应用实践(人工智能应用案例)
  17. 基于Go语言GoFrame+Vue+ElementUI实现的权限控制系统
  18. 防抖和节流的理解与实现
  19. Redist-Java 有序列表操作
  20. linux环境配置git认证

热门文章

  1. 小程序笔记(十一)之实现圆角以及倒圆角
  2. 计算机系活动主题,大学计算机系的活动方案范文2016
  3. 雷军失势小米痛哭_小米总喜欢花小钱办大事,然后就总是办不好事
  4. hpe或hp与hp 3par的关系初识之一
  5. 对抗大脑里的简单思维 ——读《清醒思考的艺术:你最好让别人去犯的52种思维错误》
  6. html图片边框左右消失,图片边框border-image的用法
  7. 阿里云注册域名创建信息模板流程及审核时间说明
  8. js手机键盘遮挡_iphone手机微信页面软键盘遮挡input输入框解决方法
  9. 教练, 我想学java的新特征
  10. 微信群收款微信服务即将来临?微信群灰度测试更多玩法