陀螺仪平衡小车实验

    之前曾尝试如何获取陀螺仪的数据,文章地址:https://www.shumeijiang.com/2021/11/09/陀螺仪模块实验-获取欧拉角.html;今天则尝试给陀螺仪加上两个轮子组装成一个二轮小车;然后利用陀螺仪数据使之保持平衡。组装小车中使用到树莓派Zero,直流电机驱动板L298N,以及可显降压升高模块。
接线示例:
实现原理:
1、获取陀螺仪Roll数据(根据陀螺仪安装方向而定);
2、定义一个平衡区间,然后对比陀螺仪的值是否在区间内;
3、当数值小于左侧边界时,小车向左移动来保持平衡;
4、当数值大于右侧边界时,小车向右移动来保持平衡;
5、当在区间内时,小车停止驱动。
代码示例:

#!/usr/bin/env python
#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
https:://www.shumeijiang.com
'''

from mpu6050 import mpu6050
#import threading
import time
import MPU6050filter
import RPi.GPIO as GPIO ##引入GPIO模块

motorA1 = 17   ##定义电机A的IN1引脚
motorA2 = 18   ##定义电机A的IN2引脚
enA = 21 #引脚21接ENA,调速电机A

GPIO.setmode(GPIO.BCM)  ##此处采用BCM编码
GPIO.setup(motorA1, GPIO.OUT)  ##设置引脚为输出模式
GPIO.setup(motorA2, GPIO.OUT)
GPIO.setup(enA, GPIO.OUT)

#初始化PWM
pwm = GPIO.PWM(enA, 40)
pwm.start(60)  ##初始化占空比

#陀螺仪数据获取
def get_mpu6050():
    sensor = mpu6050(address=0x68)
    sensor.set_gyro_range(mpu6050.ACCEL_RANGE_16G)
    sensor.set_accel_range(mpu6050.GYRO_RANGE_2000DEG)
    time.sleep(0.02)

    accel_data = sensor.get_accel_data()
    gyro_data = sensor.get_gyro_data()
    rotation = MPU6050filter.IMUupdate(accel_data['x'], accel_data['y'], accel_data['z'], gyro_data['x'], gyro_data['y'], gyro_data['z'])

    return rotation

#设置正反方向
def get_direction(direction):
        if direction == 1:
            GPIO.output(motorA1, GPIO.LOW)
            GPIO.output(motorA2, GPIO.HIGH)
        else:
            GPIO.output(motorA1, GPIO.HIGH) ##设置A1 引脚为高电平
            GPIO.output(motorA2, GPIO.LOW)  ##设置A2 引脚为低电平 如此可控制电机A正转,反之电机A反转

#根据幅度决定速度
def get_duty_cycle(val, n=1):
    val = abs(val)
    if val>10:
        val = 10
    return n*(val*6+40)

def main():
    middle = -3
    left_board = -9
    right_board = 6
    while True:
        time.sleep(0.05)
        rotation = get_mpu6050()
        roll = rotation[1]
        val = roll-middle
        print("roll is", roll)

        duty = get_duty_cycle(val, 0.6)
        if val > right_board:
            get_direction(2)
            pwm.ChangeDutyCycle(duty)
        elif val < left_board:
            get_direction(1)
            pwm.ChangeDutyCycle(duty)
        else:
            #安全区域
            pwm.ChangeDutyCycle(0)

if __name__ == '__main__':
    main()
平衡效果:
实验效果:
1、执行命令 Python jiujiang.py;
2、当小车中心失衡时,出现向左向右行走以保持平衡;
3、不过也有很多问题,当偏恒幅度过大时,小车容易出现无法保持平衡的情况;
4、由于没有经过滤波,所以小车很容易出现抖动。
视频效果:
另一个视角:

陀螺仪模块实验-获取欧拉角

    在三维空间中,我们定义分别在三个方向存在X轴,Y轴以及X轴,当物体转动时,欧拉角用来表示围绕三个轴转动的三个角度;可以用矩阵来表示;这篇文章将实验mpu6050陀螺仪如何获取欧拉角。
    其中围绕X轴旋转定义为Pitch(俯仰角);围绕Y轴旋转定义为Yaw(偏航角);围绕Z轴旋转定义为Roll(翻滚角)。
    首先建立空间坐标系,根据右手坐标系法则,右手手心面向我们,然后食指向上,中指指向我们,这时候,大拇指指向为X轴,食指指向Y轴,中指指向Z轴;如下图:
图来自网络
借用网络图片可看到三个角度运动方向:
自制一个飞机小模型,分别展示三个动作如下:
俯仰
翻滚
偏航
下面将实验mpu6050陀螺仪传感器,分别执行俯仰,翻滚,偏航动作,然后获取对应的角度。
获取陀螺仪数据,我们使用现成的模块,安装需要执行以下命令:

pip install mpu6050-raspberrypi
其他安装可参考文章:https://www.shumeijiang.com/2021/10/23/陀螺仪模块实验-准备/
实验过程:
    上面动图可见,先执行左右翻滚,可见roll数值在变化;执行前后俯仰时,pitch数值在变化;执行左右偏航时,yaw数值变化。
程序部分可参考文章: https://blog.csdn.net/weixin_38956024/article/details/94898531
算法部分参考:https://blog.csdn.net/weixin_38956024/article/details/94757023

陀螺仪模块实验-准备

    MPU6050是一款陀螺仪,它集成了3轴角速度计、3轴加速度计以及温度测量等功能;具体介绍可以网上搜索,本篇文章将介绍它如何接线以及如何通过树莓派读取数据。
    其中陀螺仪的原理是,一个旋转物体的旋转轴所指向的方向在不受外力影响时,是不会改变的;人们利用这个原理,用它来保持方向。通过I2C通信,读取轴指向的方向,将信号传送给树莓派处理。这个跟骑自行有相似之处,骑车骑的越快,车子越会沿着前进方向而不容易倾倒,因为车子有一种保持水平的力量。
    加速度是当物体在加速过程中作用在物体上的力,比如当汽车加速前进时,就有一种加速度的力,可以理解为正值;当汽车刹车时,就有一种相反方向的加速度,可以理解为负值;加速度传感器就是测量加速度的电子设备,多数加速度传感器是根据压电效应的原理在工作。
接线示例
    其中I2C协议默认是关闭的,需要手工打开,可参考文章:https://www.shumeijiang.com/2019/12/08/基于命令行打开i2c协议支持/。
    还有 I2C操作可参考文章:https://www.shumeijiang.com/2020/04/14/命令行下i2c读写操作/
    接线接好后,执行命令,可见陀螺仪模块地址:
地址为0x68
   下篇文章将介绍如何获取数据。