不思带你【从零开始】做四轴--软件/硬件/上位机--随时更新
本帖最后由 wangjt1988 于 2013-3-17 21:14 编辑很多童鞋已经拿到了套件,由于基础不同,大家在硬件焊接/模块驱动/程序调试等方面会遇到各种各样的问题,为了给大家解答,也为了方便大家少走弯路,特此开贴,从最开始的硬件焊接调试,到最后的飞行调试,一一给大家介绍,争取让大家跟着教程都能做出自己的飞控.(当然楼主也是刚开始做不久,飞机也只是可以飞行,还是很不稳定,还需要不断学习,努力)
本贴会持续,不断更新,楼主会跟着大家一同开始四轴的学习.
首先是之前帖子的链接:
开源自己的微型四轴—全套原理图.程序.上位机. http://www.amobbs.com/thread-5515784-1-1.html
匿名四轴--介绍上位机 http://www.amobbs.com/thread-5516299-1-1.html
试飞视频:http://www.56.com/u56/v_ODQ0ODczNDk.html
几个月过去了,上位机经过算法和功能的优化,现在给大家提供新版本的上位机.
大家刚开始使用可能有点摸不到头脑,这里给大家简单介绍一下 (上位机在使用时按F12会有帮助界面)
基本介绍:http://v.youku.com/v_show/id_XNTI4MDczNzI0.html
基本收发:http://v.youku.com/v_show/id_XNTI4MDc0NzEy.html
高级收码:http://v.youku.com/v_show/id_XNTI4MDc2MTMy.html
高级收码2+波形显示:http://v.youku.com/v_show/id_XNTI4MDg0NjQ4.html
飞控状态:http://v.youku.com/v_show/id_XNTI4MDk2ODk2.html
上位机的数据处理速度可以1毫秒处理一个几十字节的数据帧(无线数据包为32字节,这里就以32字节为例),也就是说1秒可以处理32000字节的数据. (1ms接收32字节的数据,并分析,显示数据波形)这里可以说是写上位机时最难的,占据了大量的时间,因为如果做到10ms接收一帧数据并显示,是比较容易的,如果频率快了,比如现在的1ms一帧数据的话,pc的数据处理和显示刷新要处理的很好才行,要不程序就很容易"死掉",因为windows不是实时系统,还有很多事情要做,不能把所有资源都给上位机程序. 目前传感器的采样频率也是1ms一次,这样就可以用上位机直接观察采样值和滤波后的值,很方便,可以实时观察滤波效果,不用再把数据先保存在内存卡或者电脑上,飞完了在调出来看波形了.
而且听取大家意见,很多人没有航模遥控,这里加上了鼠标键盘控制功能,可以用鼠标和键盘控制飞机了,当然,手感肯定没有遥控好了.
马上会有新版的飞机,遥控板,下载调试板,充电板,板子还在路上...
为了减轻重量,飞机上没有设计遥控接收模块,飞机的遥控通过飞控上自带的NRF24L01芯片完成,同时该芯片还负责数据的传输,所以飞机不能直接通过商业遥控遥控飞行,需要用一个单片机采集遥控信号再通过NRF模块发给飞机来完成遥控,同时飞机可以将飞行数据通过NRF模块发给单片机,单片机再通过串口发送到pc上位机,上位机也可以把飞行参数通过NRF模块实时发给飞机.等于是同时存在以下几个数据连接:
1:遥控->遥控板->飞机
2:PC上位机->遥控板->飞机
3:飞机->遥控板->PC上位机
可以看出所有的数据传输都要通过遥控板.这样的好处是在遥控飞行的同时可以用上位机接收飞机的飞行数据,并在上位机实时显示,上位机也可以在飞行过程中或飞机落地后,修改飞控参数,十分方便.
硬件调试:大家拿到套件后,请根据原理图进行焊接,芯片方向要注意,不清楚的找楼主要高清大图,按照图片焊接也挺简单.(完全都是贴片的元件,考验大家的焊工了.这里我们也想给大家焊接好的,但是是业余爱好搞搞这个,平时还要上班工作,实在是没有时间,还请大家理解)
焊接好后,就要开始软件调试了,这里才是四轴最"好玩"的地方,当初决定玩四轴也是因为这个,因为四轴硬件简单,主要拼的是软件,不像直机什么的,硬件太复杂了.
软件的调试,建议大家还是一步一步来.虽然我开源了飞控的全部程序,大家烧进去就可以实现基本的飞行了,但是我们自己做飞控最关键的就是程序了,直接copy一个工程过来,想必大家直接消化还是很不容易的.就像学习骑车一样,还不会走路,就学骑自行车,怎么会骑好.所以还是建议大家从基础的开始.
从哪里开始呢,因为我们使用的是stm32f103,大家就从最简单的stm32的驱动开始吧.
以下都是针对我的飞控板写的,大家如果用的自己的,记得需要把IO和端口都改为自己的
stm32可以说就是飞控的大脑,mpu6050和hmc5883就是飞控的眼睛,耳朵.飞控的所有功能,都是通过stm32实现的,所以大家清楚了stm32做什么了以后,就要好好的把他驱动好,让他按照我们的想法来运转,这样飞控才能好好的工作.
首先下载我们需要的软件环境,就是MDK (KEIL FOR ARM),我用的是4.7版本,有了自动补全功能,挺好用.当然,还要有个JLINK,使用swd方式进行调试.然后就可以开始第一步的程序编写了.按照网上的教程,使用库函数建立一个空白的工程,从最简单的,点亮一个LED开始.
要点亮一个led,也不是一件简单的事情,首先,系统时钟要配置好(最新库函数在初始化时已经帮我们把时钟初始化好了,不用我们再初始化了,当然,除非你有特殊要求),然后要配置端口的输入输出,还要打开响应端口的外设时钟.
void LED_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure; 这个是端口配置结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); 打开外设GPIOB的时钟,因为LED是通过GPIOB的9,11,14,15来驱动的
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_9 ; 选择响应的管脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 设置IO速度
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 设置IO驱动方式,out为输出,PP为推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure); 对GPIOB进行初始化
}
初始化好了,再写几个函数来操作LED,更加方便
#define LED1_OFF GPIO_SetBits(GPIOB, GPIO_Pin_11)
#define LED1_ON GPIO_ResetBits(GPIOB, GPIO_Pin_11)
#define LED2_OFF GPIO_SetBits(GPIOB, GPIO_Pin_14)
#define LED2_ON GPIO_ResetBits(GPIOB, GPIO_Pin_14)
#define LED3_OFF GPIO_SetBits(GPIOB, GPIO_Pin_15)
#define LED3_ON GPIO_ResetBits(GPIOB, GPIO_Pin_15)
#define LED4_OFF GPIO_SetBits(GPIOB, GPIO_Pin_9)
#define LED4_ON GPIO_ResetBits(GPIOB, GPIO_Pin_9)
#define LEDALL_OFFGPIO_SetBits(GPIOB, GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_9)
#define LEDALL_ON GPIO_ResetBits(GPIOB, GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_9)
这几个函数功能很简单,就是对IO的输出电平进行操作.当LED可以点亮后,更高级的比如LED的闪烁,就需要大家自己写了,实现的方法很多,可以用循环实现,也可以用定时中断实现.选用哪种方式实现,就要看具体的使用地点和情况了. 支持下,继续加油!让自己的四轴飞起来。 支持下,
顶,关注! 关注,正在储备这方面的知识,也想自己有个四轴撒{:lol:} 楼主的四轴做得很不错,严重关注中~~~~~~~~~~~~~~~~~~~~~~~~ 顶楼主。继续关注。。。 前排留名,支持!!! C#写的?
有套件吗? 顶,关注!{:lol:} william_rain 发表于 2013-3-17 18:59 static/image/common/back.gif
C#写的?
有套件吗?
delphi写的 强烈关注 {:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:victory:}{:victory:}{:victory:}{:victory:}{:victory:}{:victory:}{:victory:}{:hug:}{:hug:}{:hug:}{:hug:}{:hug:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:} 早知道早点回来看的!此贴必火,前排留不到名了!!!
准备开始,向你进军~ 顶啊,关注! 帮顶。{:lol:}{:lol:} 为楼主坚持不懈的精神赞一个! 收藏一个,一定要做一个! 支持楼主!!!! wangjt1988 发表于 2013-3-17 20:04 static/image/common/back.gif
delphi写的
LZ delphi装的是iocomp控件么?装好后OPC显示的是Evaluation么? 是iocomp,就用了基本功能,没注意opc是什么……opc是什么功能? 关注一下~~~~~~~~~~~~~ 顶!楼主好样的! 围观!!Stm32f103是个好东西哈! 楼主太强大了,谢谢楼主。 这个必须要顶!现在的版本越来越高了,把天线也一起画在板上了 顶!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! wangjt1988 发表于 2013-3-18 09:38 static/image/common/back.gif
是iocomp,就用了基本功能,没注意opc是什么……opc是什么功能?
额...其实我也不知道...
其实我也想用Delphi做个上位机,然后看到iocomp很不错,就装了,然后是这样的,据说是有试用期的... 落叶随风 发表于 2013-3-18 15:14
额...其实我也不知道...
其实我也想用Delphi做个上位机,然后看到iocomp很不错,就装了,然后是这样的, ...
能用就好 呵呵 遥控板出了没?.....套件还在待焊ing... wangjt1988 发表于 2013-3-18 15:18 static/image/common/back.gif
能用就好 呵呵
恩,不知道LZ陶瓷天线了解过没有 不错。
帮顶。
damoplus 发表于 2013-3-18 15:19
遥控板出了没?.....套件还在待焊ing...
遥控板这周就有了 期待{:titter:}{:titter:}{:titter:} 期待楼主 ,好像DIY可自己能力有限,希望得到学习提升! 我又要来顶你了{:lol:} lz 建议做大四轴。 中国无人机就靠你了 rei1984 发表于 2013-3-18 17:14 static/image/common/back.gif
lz 建议做大四轴。 中国无人机就靠你了
呵呵我倒是想为国家做贡献啊 可是咱多大能力还是知道的 额,帖子已经不能编辑了,只能在回复里贴了......
第一步LED驱动好了,下一步做点什么呢?就来驱动下串口吧,串口还是调试时一个很好用的工具.
串口调试也一样,第一步,当然是初始化.
void USART1_INIT(void)
{
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
以上是定义初始化用到的结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //¿ªÆôUSART1ʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
打开外设时钟,这里打开串口USART1时钟,那为什么打开GPIOA的时钟呢?因为串口用的GPIOA的管脚.........
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA , &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA , &GPIO_InitStructure);
管脚配置
USART_InitStructure.USART_BaudRate = 500000; 波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; 数据位
USART_InitStructure.USART_StopBits = USART_StopBits_1; 停止位
USART_InitStructure.USART_Parity = USART_Parity_No; 校验方式
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 流控制
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; 收发模式
USART_ClockInitStruct.USART_Clock = USART_Clock_Disable; 时钟及其他设置
USART_ClockInitStruct.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStruct.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStruct.USART_LastBit = USART_LastBit_Disable;
USART_Init(USART1, &USART_InitStructure); 串口初始化,刚才的都不算初始化,只是修改变量,这里才把变量赋值给寄存器
USART_ClockInit(USART1, &USART_ClockInitStruct); 串口时钟初始化
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 开中断
USART_Cmd(USART1, ENABLE); 使能串口
} 串口初始化好了,就要测试收发了,将串口用串口线和电脑连接起来,先来简单的发送,用上位机看看能不能收到数据.
对了 这里还要设置串口中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
我用的第二组,串口给了优先级3,subfriority3
串口中断函数:
void USART1_IRQHandler(void)
{
USART1_IRQ();
}
void USART1_IRQ(void)
{
if(USART_GetITStatus(USART1,USART_IT_TXE)!=RESET)
{
发送中断
}
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
接收中断
}
} 本帖最后由 wangjt1988 于 2013-3-18 18:58 编辑
中断也写好后,基本的发送接收应该就没问题了.
但是在使用过程中,没有一个缓冲区肯定是不行的,关于这方面的帖子很多,大家在论坛上搜索下吧.我就简单介绍下我用的简单的环形缓冲吧.
我用了一个环形发送缓冲,比如一个长度为100字节的数组,再定义两个变量,比如num与t_num
num表示缓冲区内下一个空字节在第几字节,t_num表示下一个需要发送的字节在缓冲区的多少字节
比如需要发送12345 这5个数字,分别写入数组的01234字节,共5字节,此时num+=5,表示buf是空的.写入数据后,激活发送,发送完一个字节,t_num+1,并判断t_num与num的大小,如果t_num<num,就急需发送,如果t_num=num,说明数据已经发送完了.
大致意思就是这样,不知道我表达清楚了没有. 串口做好了,再做点什么呢,就Timer吧,这个是以后程序里很重要的一个内容,因为timer是用来计时的,我们以后要用它来触发做很多事情,比如定时去读传感器并控制电机等等.
还是一样,先初始化Timer,以TIMER3为例
void TIM3_INIT(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
初始化使用的结构体
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
打开timer3的时钟
TIM_DeInit(TIM3);
将timer3寄存器设置为默认
TIM_TimeBaseStructure.TIM_Period=1000; 这个寄存器我理解是比较值,就是用这个值来和cnt比较,判断是否溢出(大于这个数就溢出)
TIM_TimeBaseStructure.TIM_Prescaler=72-1;这个寄存器我理解是分频值,就是timer3的时钟除以这个值+1就是计数器的时钟,这里72分频,就是1M,刚才比较值设置为1000,那么溢出的频率就是1000HZ,也就是每次中断1MS
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 采样分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 向上计数
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); 时钟初始化
TIM_ClearFlag(TIM3,TIM_FLAG_Update); 清楚标志
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); 开中断
TIM_Cmd(TIM3,ENABLE); 使能timer3
} 鉴定完毕!本贴对于我们这些小白来说是福利,彻底的福利 楼主大公无私 必须要顶,共同娱乐。 有人让我解释一下我程序里面PID计算的过程,这里就插一节吧,就是介绍下我的PID,当然,还很不完善,后期肯定还要经过很多改动才行,这里就先介绍下现在的"初级版"吧.
void PID_CAL(void) PID计算函数
{
static float thr=0,rool=0,pitch=0,yaw=0; 控制量
static float rool_i=0,pitch_i=0; 积分
int16_t Motor1,Motor2,Motor3,Motor4; 四个电机输出
IMU_TEST(); 计算姿态
GET_EXPRAD(); 获得控制量
////////////////////////////////////////////////////////////////////////////////
rool = PID_RP.P * DIF_ANGLE.X; roll方向的P计算
if(Q_ANGLE.Rool>-0.1 && Q_ANGLE.Rool<0.1) 判断I是否需要清零
{
rool_i = 0;
}
rool_i -= PID_RP.I * Q_ANGLE.Rool; I计算
PID_RP.IMAX = DIF_ANGLE.X * 10; 积分限幅
if(PID_RP.IMAX<0)
{
PID_RP.IMAX = (-PID_RP.IMAX) + 100;
}
else
{
PID_RP.IMAX += 100;
}
if(rool_i>PID_RP.IMAX) rool_i = PID_RP.IMAX;
if(rool_i<-PID_RP.IMAX) rool_i = -PID_RP.IMAX;
rool += rool_i; 积分
rool -= PID_RP.D * GYRO_F.X; D计算
///////////
pitch = PID_RP.P * DIF_ANGLE.Y; 同上
if(Q_ANGLE.Pitch>-0.1 && Q_ANGLE.Pitch<0.1)
{
pitch_i = 0;
}
pitch_i -= PID_RP.I * Q_ANGLE.Pitch;
if(PID_RP.IMAX<0)
{
PID_RP.IMAX = (-PID_RP.IMAX) + 100;
}
else
{
PID_RP.IMAX += 100;
}
if(PID_RP.IMAX<0) PID_RP.IMAX = -PID_RP.IMAX;
if(pitch_i>PID_RP.IMAX) pitch_i = PID_RP.IMAX;
if(pitch_i<-PID_RP.IMAX) pitch_i = -PID_RP.IMAX;
pitch += pitch_i;
pitch -= PID_RP.D * GYRO_F.Y;
/////////////
GYRO_I.Z += EXP_ANGLE.Z/3000; yaw方向就简单的用了陀螺的积分 PD
yaw = -10 * GYRO_I.Z;
yaw -= 3 * GYRO_F.Z;
//
thr = RC_DATA.THROTTLE+400;
////////////////////////////////////////////////////////////////////////////////将控制量输出给电机
Motor1=(int16_t)(thr + rool - pitch + yaw);
Motor2=(int16_t)(thr + rool + pitch - yaw);
Motor3=(int16_t)(thr - rool + pitch + yaw);
Motor4=(int16_t)(thr - rool - pitch - yaw);
if(FLY_ENABLE && (RC_DATA.THROTTLE>-400)) 和解锁有关,未解锁或油门太低电机禁止转动
MOTO_PWMRFLASH(Motor1,Motor2,Motor3,Motor4);
else
MOTO_PWMRFLASH(0,0,0,0);
}
程序就这么简单,当然还需要很多改进,PID参数也需要慢慢调试才行 搬凳子,听楼主悉心教诲 chliken 发表于 2013-3-18 21:12
搬凳子,听楼主悉心教诲
教诲谈不上啊…只是把我的思路跟大家聊一聊 外形很漂亮,看起来不错。 落叶随风 发表于 2013-3-18 15:22 static/image/common/back.gif
恩,不知道LZ陶瓷天线了解过没有
你了解陶瓷天线吗?我曾经试过,效果不怎么好,不知道是不是我买的天线有问题 楼主强大啊,火 顶一下 期待中 小号 发表于 2013-3-19 13:02 static/image/common/back.gif
你了解陶瓷天线吗?我曾经试过,效果不怎么好,不知道是不是我买的天线有问题 ...
我不太了解,想用陶瓷天线来着,不知道怎么选 现在能力还达不到不过先mark 想了解一下做PCB天线有什么具体注意事项和要求呢? wangjt1988 发表于 2013-3-19 08:50 static/image/common/back.gif
教诲谈不上啊…只是把我的思路跟大家聊一聊
看着三个帖子而来的,想不到又出新教程了,赞一个,预定了 继续支持!!!!!!!!!! wangjt1988 发表于 2013-3-18 20:36 static/image/common/back.gif
有人让我解释一下我程序里面PID计算的过程,这里就插一节吧,就是介绍下我的PID,当然,还很不完善,后期肯定还 ...
你的代码我看过了,用到了四元数,但是最后又把四元数转换成欧拉角进行PID控制,不知道,这里面用到四元数是不是有必要 楼主可以否把视频传输也加上呢{:lol:} xaper 发表于 2013-3-20 14:42 static/image/common/back.gif
你的代码我看过了,用到了四元数,但是最后又把四元数转换成欧拉角进行PID控制,不知道,这里面用到四元 ...
对四元数直接参加控制还不懂呢......希望有个教程学习一下,请问你知道怎么用四元数直接控制么 工程师030 发表于 2013-3-20 16:48 static/image/common/back.gif
楼主可以否把视频传输也加上呢
没有摄像头..... 这个可以学习 串口/TIMER都讲过了,这次讲点什么呢,稍微提一提怎么调试吧,因为今天群里有人问我串口是用来做什么的?这个问题让我一下懵了.这该怎么回答?
串口,在我们这个工程里,其实就是用来调试的,无线控制是通过SPI来进行,其实无线调试好以后,串口也就没有用了,可以使用无线进行调试的,这样更加方便.其实串口是完全可以省略的.
那么怎么使用这个串口呢?串口可以理解为一根网线,通过他,可以将飞机上的数据传输到电脑上,就这么简单.........至于传什么,怎么传,学问就大了....
串口驱动好以后,可以帮助我们分析很多问题,有些甚至JLINK也做不到,观察变量,观察标志位,观察程序运行状态,等等,都可以通过串口来实现,上位机为了配合串口和无线调试,还特意做了一个DEBUG功能,就是为了帮助大家更方便的调试,可以通过串口发送一个自定义的命令,打开上位机的LED,或者改变上位机显示的寄存器数字.这样可以帮助大家知道程序的执行状态,比如中断进入没进入啊,进入的频率啊,变量现在的值是多少啊等等信息.
我这里仅仅是一点点自己的调试经验,至于怎么发送,发送一个什么样的格式,大家个人习惯不同,写出来当然也各不相同,有人喜欢用printf,我就喜欢十六进制,各有长短 强人 {:victory:} 本帖最后由 wangjt1988 于 2013-3-21 20:23 编辑
可能一个模块一个模块的讲有些啰嗦,而且这些模块的使用方法网上也有很多教程,我以后就不在说这个了.大家有问题就搜索下吧,很容易找到.我目前用到的外设有:timer,usart,iic,spi,flash,gpio,exit,暂时就这么多.
今天想跟大家谈谈加速度计和陀螺仪,不少人在问加速度计陀螺仪的数据读出来了怎么用,咱们就从这两个传感器的特点开始了解下,了解了特点,用法就很容易了.
以下仅代表个人观点,有哪里不对,还请指出....
做个比喻吧,加速度计,以下简称加计,大家可以把它想象成一个铁块,这个铁块是个立方体,有前后左右上下六个面,每个面连接有一个弹簧,弹簧另一端假设固定在一个卡车的集装箱里面,这样这个铁块就被这六个弹簧吊在集装箱里面了,由于铁块有重力,所以汽车不动时,上面的弹簧被拉长,下面的弹簧被压缩,这里假设是通过测量弹簧的拉力来输出加速度(实际有可能是电容什么的,这里不做讨论,了解特性就好),六个弹簧,两两一组,正好3个轴,这就是3轴加速度了,静止不动时,只有Z轴也就是上下两根弹簧有读数,其他两对弹簧是平衡的.现在假设汽车在做加速运动,那么不仅仅上下两根弹簧不平衡了,前后两根弹簧也会有变化,前面的弹簧拉长,后面的弹簧压缩,就有了前后方向的加速度.左右也是一个道理.
知道了加计的大致原理,那么加计有什么特点呢?让我们大家想象一种情况,就是这辆卡车行驶在颠簸的路上,集装箱里面的铁块肯定不会稳稳的吊着了,他会随着汽车左摇右摆,上下颠簸,而且有一点大家注意,铁块的此时的摆动,不是完全和汽车同步的,由于惯性等原因,铁块会在里面"乱动",荡来荡去,此时的加速度输出会是怎么样的呢?肯定也是随着铁块"荡来荡去",所以我们得出加计的一大特点,就是对震动很"敏感",如果把飞控板放在桌子上静止不动,可以说随便一个姿态算法的输出都不错,哪怕不滤波.可以当电机一转动起来,震动来了,加计就有了很大的干扰,此时如果处理不好,姿态就乱掉了.
然后我们再说说陀螺仪,陀螺仪顾名思义,肯定和陀螺有很大关系,没错,特点也和陀螺一样.还是假设在这个车里面,我们放上一个小时候玩的陀螺,不管用了什么方法,让它高速旋转起来,大家都知道,这样陀螺是不会倒的,他会尽量保持当前的姿态,陀螺仪正是利用这个特点.我们看两段视频来了解下.
http://v.youku.com/v_show/id_XMjI5MTc4MjI4.html
http://v.youku.com/v_show/id_XNDIxODk5MDAw.html
通过视频,大家可以看到,陀螺在高速旋转时,是会尽量保持转轴不变的.那么我们就可以想到陀螺仪的特点了,就是对震动是"不敏感"的,因为它会尽量保持自己不被震动改变,但是陀螺会不断累积误差,造成"漂移".
好了,这里我们知道了加计和陀螺仪的特点,再考虑怎么使用,就简单多了,总的来说就是加计短时间不可靠,因为震动,陀螺仪长时间不可靠,因为"漂移".那么对于加计的数据和陀螺仪的数据,我们就应该短时间相信陀螺仪,长时间相信加速度.好了,到了这里,再怎么做也就清晰了,对加速度的数据,我们要滤波,平均值滤波等等,方法很多,对陀螺仪数据,我们积分,短时间内,这个积分得到的角度还是准确的,而过一段时间,就用处理过的加速度数据来矫正陀螺仪积分的角度,抑制"漂移".这样利用两个传感器的特点,取长补短,来达到一个相对稳定的输出.
以上都是个人看法,有什么不对还请大家指出,大家多多讨论. 很形象的描述 mark 要好好学学~ 一直在跟进,记下,顶上. 看完忘顶贴了,补上 写的不错,谢谢分享,改天我也上传个关于惯性量传感器的介绍。 不错,想搞个套件跟着学习 jordonwu 发表于 2013-3-21 23:02 static/image/common/back.gif
不错,想搞个套件跟着学习
嗯大家一同学习 进步写一套自己的东西 kinghawk 发表于 2013-3-21 23:01 static/image/common/back.gif
写的不错,谢谢分享,改天我也上传个关于惯性量传感器的介绍。
真是太好了,我们也跟着学习些知识 西门子的传感器介绍
比较直观、形象 {:lol:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:} 版主速更啊{:lol:} 还是喜欢看原理图 通过陀螺仪控制 四个直流有刷电机,PWM控制 yun20 发表于 2013-3-23 20:36 static/image/common/back.gif
版主速更啊
这几天忙着测试板子和学习opengl,看能不能在上位机加上3D显示,大家不要着急啊,有时间马上更新 顶一个啊! 帮顶…
来自:amoBBS 阿莫电子论坛 Windows Phone 7 客户端 强烈关注{:lol:}{:lol:} 关注................ 犀利!数据很稳定! 搬个板凳,站好位。。。。请教楼主一个问题,四元数解算时的误差是用PI修正的,可否加入卡尔曼滤波修正,我一直没想通怎么做 mazhenyu 发表于 2013-3-24 13:48
搬个板凳,站好位。。。。请教楼主一个问题,四元数解算时的误差是用PI修正的,可否加入卡尔曼滤波修正,我 ...
我也想加上呢,也是不懂,卡尔曼还没理解,数学不好…… wangjt1988 发表于 2013-3-24 16:31 static/image/common/back.gif
我也想加上呢,也是不懂,卡尔曼还没理解,数学不好……
哎,什么东西到高处都是数学呀,硬伤。。。最近毕设要用自抗扰控制,感觉比PID好多了,就是各种数学各种看不懂 今天跟大家谈一谈6050的数据吧,首先,量程,
GYRO: ±250, ±500, ±1000, and ±2000°/sec (dps). 这是什么意思呢,就是陀螺数据在输出32767(也就是int16型数据的最大值)的时候,分别表示250度每秒一直到2000度每秒.
ACC: ±2g, ±4g, ±8g, and ±16g.表示输出32767时表示2倍重力加速度一直到16倍重力加速度.
量程选的小,数据就准确一些(在量程范围内),但是在剧烈动作时,容易超调.
知道了量程和数据的意义,怎么把输出的数据转成角度想必就很简单了吧.
acc的数据出来后,进行一个移动平均值滤波,作用就是个低通滤波,gyro的数据换成角度,积分,就可以得到"姿态角",这里直接得到的姿态角是不对的,要对三轴数据进行"解耦"---应该是这么叫,这个我就不太懂了,大家可以参考一下mwc的程序或者网上寻找教程.
得到了角度,定期用acc的角度来矫正陀螺的误差,就可以实现自稳这个功能了. 给力,楼主继续加油!!! 占楼,顶楼主 顶呀,,第一次有人这样详细讲四轴,期待呀!!! 再次顶楼主的伟大共享精神。。 楼主现在程序有更新吗?
学习一下.... 加油 正在弄 学习一下.... 楼主速更啊,期待 坐等。。。 感谢楼主的无私分享~~~
套件怎么弄到呢 本帖最后由 wangjt1988 于 2013-3-31 01:20 编辑
这几天没有更新,专心学习了下3D,给上位机增加了3D模型显示
楼主能不能共享一下MDK版本的工程文件呢? cuiliang1984 发表于 2013-3-31 19:31 static/image/common/back.gif
楼主能不能共享一下MDK版本的工程文件呢?
MDK的刚开始写