直立代码分析__两轮平衡小车原理
生活随笔
收集整理的這篇文章主要介紹了
直立代码分析__两轮平衡小车原理
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本文依據(jù)網(wǎng)上資源整理而來,適用于初學(xué)直立車者。
一、原理
平衡小車是通過兩個電機(jī)運(yùn)動下實現(xiàn)小車不倒下直立行走的多功能智能小
車,在外力的推拉下,小車依然保持不倒下。這么一說可能還沒有很直觀的了解
究竟什么是平衡小車,不過這個平衡小車實現(xiàn)的原理其實是在人們生活中的經(jīng)驗
得來的。如果通過簡單的練習(xí),一般人可以通過自己的手指把木棒直立而不倒的
放在指尖上,所以練習(xí)的時候,需要學(xué)會的兩個條件:一是放在指尖上可以移動
二是通過眼睛觀察木棒的傾斜角度和傾斜趨勢(角速度)。通過手指的移動去抵
消木棒傾斜的角度和趨勢,使得木棒能直立不倒。這樣的條件是不可以缺一的,
實際上加入這兩個條件,控制過程中就是負(fù)反饋機(jī)制。
而世界上沒有任何一個人可以蒙眼不看,就可以直立木棒的,因為沒有眼睛
的負(fù)反饋,就不知道筆的傾斜角度和趨勢。這整個過程可以用一個執(zhí)行式表達(dá):
?
?
?
?
?
?
?
?
?
二、平衡代碼
balance.c
#include "Balance.h"S_FLOAT_XYZ GYRO_Real, // 陀螺儀轉(zhuǎn)化后的數(shù)據(jù)ACC_Real, // 加速度計轉(zhuǎn)化后的數(shù)據(jù)Attitude_Angle, // 當(dāng)前角度Last_Angle, // 上次角度Target_Angle; // 目標(biāo)角度S_INT16_XYZGYRO, // 陀螺儀原始數(shù)據(jù)GYRO_Offset, // 陀螺儀溫飄GYRO_Last, // 陀螺儀上次數(shù)據(jù)ACC, // 加速度計數(shù)據(jù)ACC_Offset, // 加速度計溫飄ACC_Last; // 加速度計上次數(shù)據(jù) S_INT32_XYZTar_Ang_Vel, // 目標(biāo)角速度Tar_Ang_Vel_Last; // 上次目標(biāo)角速度int32 Speed_Now = 0, // 當(dāng)前實際速度Speed_Min = 0, // 左右最小速度Speed_Set = 0, // 目標(biāo)設(shè)定速度Theory_Duty = 0,// 理論直立占空比Vel_Set = 0, // 目標(biāo)轉(zhuǎn)向角速度Direct_Parameter = 0,// 轉(zhuǎn)向系數(shù)Direct_Last = 0,Radius = 0; // 目標(biāo)轉(zhuǎn)向半徑倒數(shù)uchar Point = 80; int32 Difference = 0;/* 各種標(biāo)志位,放定時器中進(jìn)行時序控制 */ char Speed_Flag, Angle_Flag, Ang_Velocity_Flag, DMP_Flag; /********************************************************//********************* 串級平衡控制 *********************/ // 頻率控制在定時器中設(shè)置 void Balance_Control(void) {if (Ang_Velocity_Flag) // 直立角速度環(huán) 2ms{Ang_Velocity_Flag = 0;MPU6050_GetData(&GYRO, &ACC); // 讀取陀螺儀數(shù)據(jù)Data_Filter(); // 對原始數(shù)據(jù)滑動濾波 /* 角速度環(huán)作為最內(nèi)環(huán)控制直立 */Theory_Duty += PID_Increase(&Ang_Vel_PID, Ang_Vel, (int32)(GYRO_Real.Y*10), (int32)(Tar_Ang_Vel.Y)); // 計算直立PWM (int32)(Tar_Ang_Vel.Y)Theory_Duty = range_protect(Theory_Duty, -950, 950);// if (System_OK) // { //Speed_Min // Direct_Parameter = PID_Realize(&Direct_PID, Direct, (int32)(GYRO_Real.Z*100), Radius*Speed_Min);// 轉(zhuǎn)向環(huán)左正右負(fù) // Direct_Parameter = range_protect(Direct_Parameter, -1200, 1200); // } // // Direct_Last = Direct_Last*0.3 + Direct_Parameter*0.7; // 更新上次角速度環(huán)結(jié)果MOTOR_Duty_Left =Theory_Duty ; // 左右電機(jī)根據(jù)轉(zhuǎn)向系數(shù)調(diào)整差速- Direct_LastMOTOR_Duty_Right =Theory_Duty ; //+ Direct_Last // if (Run_Flag) // {MOTOR_Control(MOTOR_Duty_Left, MOTOR_Duty_Right); // 控制左右電機(jī) // } // else // { // if (Stop_Flag) // { // if (Speed_Now > 20) // { // MOTOR_Control(-350, -350); // } // else // { // MOTOR_Control(0, 0); // } // } // // else // { // MOTOR_Control(0, 0); // } // }Get_Attitude();mpu_dmp_get_data(&Attitude_Angle.Y, &Attitude_Angle.X, &Attitude_Angle.Z); // 使用DMP直接讀取歐拉角} if (Angle_Flag) // 直立角度環(huán) 10ms{Angle_Flag = 0; Speed_Measure();// 獲取當(dāng)前速度/* 角度環(huán)加到角速度環(huán)上串級控制 */Tar_Ang_Vel.Y = PID_Realize(&Angle_PID, Angle, (int32)(Attitude_Angle.Y*100), (int32)Target_Angle.Y); // 結(jié)果為放大10倍的目標(biāo)角速度 (int32)Target_Angle.Y // Tar_Ang_Vel.Y = range_protect(Tar_Ang_Vel.Y, -1500, 1500); // 注意正負(fù)號}if (Speed_Flag) // 速度環(huán) 100ms{Speed_Flag = 0;Target_Angle.Y = PID_Realize(&MOTOR_PID, MOTOR, Speed_Now, Speed_Set); // 結(jié)果為放大100倍的目標(biāo)角度Target_Angle.Y += Zero_Angle*100; // 目標(biāo)角度疊加在零點(diǎn)上 // Target_Angle.Y = range_protect((int32)Target_Angle.Y, 1000, 4000); // -44 22Speed_Min = Speed_Min * 0.1 + Speed_Now * 0.9;if (Speed_Min < 40){Speed_Min = 40;}} }/* 初始化用到的一些變量 */ void Balance_Init(void) {Attitude_Angle.Y = 0;Target_Angle.Y = 0;Tar_Ang_Vel.Y = 0;Tar_Ang_Vel.Z = 0; }?balance.h
#ifndef __BALANCE_H__ #define __BALANCE_H__ #include "common.h" #include "include.h"#define Zero_Angle -37.8f // 藍(lán)色電池-3.8 //#define Zero_Angle 22.0f // 白色電池extern S_FLOAT_XYZ GYRO_Real, // 陀螺儀轉(zhuǎn)化后的數(shù)據(jù)ACC_Real, // 加速度計轉(zhuǎn)化后的數(shù)據(jù)Attitude_Angle, // 當(dāng)前角度 Last_Angle, // 上次角度Target_Angle; // 目標(biāo)角度extern S_INT16_XYZGYRO, // 陀螺儀原始數(shù)據(jù)GYRO_Offset, // 陀螺儀溫飄GYRO_Last, // 陀螺儀上次數(shù)據(jù)ACC, // 加速度計數(shù)據(jù)ACC_Offset, // 加速度計溫飄ACC_Last; // 加速度計上次數(shù)據(jù) extern S_INT32_XYZTar_Ang_Vel, // 目標(biāo)角速度Tar_Ang_Vel_Last; // 上次目標(biāo)角速度extern int32 Speed_Now, // 當(dāng)前實際速度Speed_Min, // 左右最小速度Speed_Set, // 目標(biāo)設(shè)定速度Vel_Set, // 目標(biāo)轉(zhuǎn)向角速度Direct_Parameter,Radius;extern uchar Point; extern int32 Difference;extern char Speed_Flag, Angle_Flag, Ang_Velocity_Flag, DMP_Flag; //extern float Zero_Angle ; void Balance_Control(void); void Balance_Init(void);#endif?
總結(jié)
以上是生活随笔為你收集整理的直立代码分析__两轮平衡小车原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【直达本质讲运放】运放的“第一原理”式定
- 下一篇: 广域网(PPP协议和HDLC协议)