两轴舵机云台的一点实践

  • 效果演示
  • 硬件使用情况
  • 定时器中断代码
  • 计算机体系下的云台角代码
  • 舵机控制代码
  • 工程源码下载

简介:
为了学习姿态解算相关知识,最近做了一个作品,模仿炮塔跟随系统,用陀螺仪使两个舵机指向空间中的某一特定方向,实际上用欧拉角旋转矩阵法只完成了功能,然后针对舵机延迟问题做了一个微分控制。但由于欧拉角不能解算全姿态,实际能稳定的角度并不大, 将旋转矩阵换成四元数来表示之后解算结果不对,不知道是小弟哪里弄错了?东西很多纯属瞎扯,望大佬们轻喷。

效果演示

视频: 两轴舵机云台

硬件使用情况

陀螺仪:MPU6050 *1
舵机:MG996R *2
主控芯片:STM32F103C8T6 *1

定时器中断代码

这部分代码使用TIM2定时器中断提供100Hz的控制频率,并且针对舵机位置控制延迟的问题,对舵机位置做了一个微分比例补偿控制,提高了响应速度。这部分代码在 main.c 里面。

// 全局变量声明float pitch,roll,yaw;   //欧拉角   float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;//四元数float hy=0,hp=0;               //参考系下云台角float by,bp,br;         //参考系下姿态角(也就是欧拉角)float bhy=0,bhp=0,bhr=0;//机体系下云台角float Kd1=10.0;                    //舵机1补偿系数   float Kd2=10.0;                    //舵机2补偿系数   /********************************************/
//定时器2中断服务程序 周期:10ms  频率:100Hz
void TIM2_IRQHandler(void)   //TIM2中断
{static int t=0;u8 button;float bhylast=0, bhplast=0;         //机体系下上一时刻的云台角float bhyincre=0, bhpincre=0;      //机体系下上一时刻的云台角增量float bhycomp = 0, bhrcomp = 0;                 //舵机转角度补偿量,与角速度有关if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)     //检查TIM2更新中断发生与否{   TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );    //清除更新中断标志    bhylast=bhy, bhplast=bhp;                 //记录机体系下上一时刻的云台角if(mpu_dmp_get_data(&roll,&pitch,&yaw)==0)   //更新姿态角(由于安装问题实际roll和pitch互换了){ yaw=-yaw, pitch=-pitch, roll=-roll;     //由于安装问题实际yaw,roll,pitch均倒向           CalHeadDegree();               //利用欧拉角旋转矩阵计算机体系下的云台角:hby,hbpbhyincre = bhy - bhylast;      //计算云台转动角速度bhpincre = bhp - bhplast;    bhycomp = Kd1*bhyincre;         //计算舵机1补偿量bhrcomp = Kd2*bhpincre;        //计算舵机2补偿量HeadTurnToXY(bhy+bhycomp ,bhp+bhrcomp);    //进行角度补偿输出t++;if(t>=10)t=0,   LED0=!LED0;  //每10*10=100ms闪动 }   }
}

计算机体系下的云台角代码

这个函数将云台在参考坐标系内的指向向量旋转到机体系去,并且化为机体系下的云台角,注释掉的部分是用四元数表示的旋转矩阵,此部分放在 servo.c 里面。


/********************************************/
void CalHeadDegree(void)      //计算机体系下的云台角
{const float DEG2RAD = 0.0174533;   //度化弧度因子const float RAD2DEG = 57.29578 ;   //弧度化度因子float xn=cos(hy*DEG2RAD)*cos(hp*DEG2RAD);   //参考系下的云台指向向量float    yn=sin(hy*DEG2RAD)*cos(hp*DEG2RAD);float zn=sin(hp*DEG2RAD);           float xb,yb,zb,normalizer;             //机体系下的云台指向向量、模长float cby,sby,cbp,sbp,cbr,sbr;       //姿态角的正余弦值
//  printf("xn:%f\tyn:%f\tzn:%f\r\n",xn,yn,zn);normalizer = invSqrt(xn*xn + yn*yn +zn*zn);   //求出向量模长的倒数       xn *= normalizer;          //向量单位化yn *= normalizer;zn *= normalizer; bp=pitch,br=roll,by=yaw;             //先算出姿态角的三角值方便计算cby=cos(by*DEG2RAD),sby=sin(by*DEG2RAD);       cbp=cos(bp*DEG2RAD),sbp=sin(bp*DEG2RAD);cbr=cos(br*DEG2RAD),sbr=sin(br*DEG2RAD);
//  printf("yaw:%f\tpitch:%f\troll:%f\r\n",yaw,pitch,roll);xb =                 cbp*cby*xn                 + cbp*sby*yn      -sbp*zn;//套用欧拉角旋转矩阵公式yb = (sbr*sbp*cby - cbr*sby)*xn + (sbr*sbp*sby + cbr*cby)*yn + sbr*cbp*zn;zb = (cbr*sbp*cby + sbr*sby)*xn + (cbr*sbp*sby - sbr*cby)*yn + cbr*cbp*zn;
//  printf("xb:%f\tyb:%f\tzb:%f\t",xb,yb,zb);//   xb = (q0*q0+q1*q1-q2*q2-q3*q3)*xn + 2*(q1*q2-q0*q3)*yn + 2*(q1*q3+q0*q2)*zn;//套用四元数旋转矩阵公式
//  yb = 2*(q1*q2+q0*q3)*xn +(q0*q0-q1*q1+q2*q2-q3*q3)*yn + 2*(q2*q3-q0*q1)*zn;
//  zb = 2*(q1*q3-q0*q2)*xn + 2*(q2*q3+q0*q1) *yn + (q0*q0-q1*q1-q2*q2+q3*q3)*zn;
//  xb=yb, yb=-xb;normalizer = invSqrt(xb*xb + yb*yb +zb*zb);   //求出向量模长的倒数        xb *= normalizer;          //向量单位化yb *= normalizer;zb *= normalizer;
//  printf("normalizer:%f\r\n",normalizer);//利用几何关系计算机体系下的云台角 bhp = asin(zb)*RAD2DEG;                                                bhy = acos( xb*invSqrt(xb*xb+yb*yb) )*RAD2DEG;        bhp = -bhp;                                             //加上正负号if(yb<0) bhy=-bhy;
//  printf("bhp:%f\tbhy:%f\r\n",bhp,bhy);
}

舵机控制代码

以下函数用来控制舵机,使它们指向机体系下的一个方向 (hby,hbp)
水平角hby:-90°~90° 俯仰角hbp: 0°~180° ,放在 servo.c 里面。


/********************************************/
/************************************************/
void Servo1RunToDegree(float degree)   //舵机1转到degree角度,degree:-90~90
{float pwm;if(degree>=-120 && degree<=120){pwm = 1.0394*degree + 1848.55;TIM_SetCompare2(TIM3,pwm);   //修改比较值,修改占空比}
}
void Servo2RunToDegree(float degree)   //舵机2转到degree角度,degree:0~180
{float pwm;if(degree>=-30 && degree<=210){pwm = -1.0306*degree + 1939.10; TIM_SetCompare1(TIM4,pwm);  //修改比较值,修改占空比    }
}/************************************************/
void HeadTurnToXY(float x,float y)       //云台转到水平x,俯仰y位置, x:-90~90, y:0~180
{Servo1RunToDegree(x);Servo2RunToDegree(y);
}

工程源码下载

链接:https://pan.baidu.com/s/1f9QcTQm-TCXQcAJTKidhYg
提取码:rggw

参考资料: 四元数姿态解算 (来源网络,侵权请联系我删除,感谢作者整理)

两轴舵机云台的一点实践相关推荐

  1. 两轴机械臂+机械爪整体控制板设计与机械爪控制调试

    简 介: 在实验室样品自动上样双轴机械臂调试之后,出现了肩关节的运动力矩不足,这里使用了57HSXXXX步进电机进行增加力矩.下面是相关的调试过程. 关键词: 两轴机械臂,机械爪,上样机械臂 01为什 ...

  2. Raspberry Pi 4B 同步控制两个舵机 实现颜色跟踪

    组件: Raspberry Pi 4B 2G 5V TS90A 舵机 2个 转动角度:0°~180° 工作电压:4.8V-5V 控制信号:PWM 50HZ/0.5-2.5MS 摄像头 环境 Pytho ...

  3. 两轴插补速度怎么给定_快速入门 | 篇十七:运动控制器多轴插补运动指令的使用...

    以下是图文详解 本节内容主要分为三大部分:插补运动.轨迹前瞻以及SP速度指令. 一 插补运动 插补是机床数控系统依照一定方法确定刀具运动轨迹的过程,插补是一个实时进行的数据密化的过程,不论是何种插补算 ...

  4. 【灯哥开源四足机器人】推荐一个开源四足机器狗项目,8自有度,两个舵机控制一个腿,apache开源协议的,已经迭代了好多个版本了,设计的非常好。有官方淘宝店,没有3D打印机的可以购买散装零件自己组装

    目录 前言 1,关于[灯哥开源四足机器人] 2,使用py-apple 3,总结 前言 本文的原文连接是: https://blog.csdn.net/freewebsys/article/detail ...

  5. 树莓派笔记13:舵机云台(一)

    最近买了个小型舵机云台模块来玩,淘宝上卖这个的挺多的,一般三四十块钱,很多还卖配套的摄像头.说是云台,其实就是用两个舵机结合固定板做的支撑模块,两个舵机分别控制左右和上下的转动. 1 关于舵机 首先了 ...

  6. 制作一个舵机云台【内附资料下载链接】

    1.运动功能说明 舵机云台下方的舵机可以提供一个左右摆动的动作,同时上方横置的关节模组可以提供一个上下摆动的动作.在这两部分的配合下,云台的执行端端(即:关节模组的U型支架)可以灵活地走出一个近似半球 ...

  7. 树莓派云台舵机怎么用_人脸辨识,用树莓派Raspberry Pi实现舵机云台追踪脸孔

    影像辨识作为近年最热门的专业技术之一,广泛用于智慧监视器.车电监控.智慧工厂.生物医疗电子等等:其中,人脸辨识是一个很重要的部分,网络上已经有相当多的资源可供下载使用:于是我们使用舵机云台作为镜头旋转 ...

  8. 求两点连线与其中一点为球心球的交点——赋MATLAB代码

    在轨迹规划过程中,常将其它智能体视为具有一定半径的球形障碍物(或圆形障碍物).若求智能体与障碍物最近的边缘点,其本质即求两点连线与其中一点为球心球的交点. 求的方法有多种,这里采用雅克比矩阵的方法. ...

  9. 阿波罗服务器的投资项目,阿波罗未来产业城调整规划范围 将重点打造“两轴一片”空间格局...

    阿波罗未来产业城重点打造"两轴一片"空间格局. 记者3月6日从园山街道了解到,位于该街道的阿波罗未来产业城规划范围进行调整,从原来的44.54平方公里调整为17.21平方公里.调整 ...

最新文章

  1. Go 中 time.Parse 报错:year/month/day hour/minute/second out of range 时间格式化为什么是 2006-01-02 15:04:05?
  2. [CVPR 2020] RandLA-Net:大场景三维点云语义分割新框架(已开源)
  3. Symmetric Pairs(连接、分组,聚合)
  4. 组件间数据交互——组件插槽的作用||具名插槽用法|| 作用域插槽
  5. 两个例子详解并发编程的可见性问题和有序性问题,通过volatile保证可见性和有序性以及volatile的底层原理——缓存一致性协议MESI和内存屏障禁止指令重排
  6. 如何修改uboot的环境变量env的值来指定uImage的名字
  7. 【C语言基础】C语言异常捕获机制 - setjmp
  8. [python机器学习及实践(2)]Sklearn实现朴素贝叶斯
  9. 问题三十八:C++中bad alloc问题(1)——分析问题
  10. 力扣题目系列:605. 种花问题
  11. C语言pow函数编写
  12. ONOS架构中的YANG、P4 Runtime
  13. 编程需要知道多少数学知识?
  14. c语言作业陌路寒暄,短学期算法与编程实习的C语言题目
  15. C语言画圆(详细解释易懂)
  16. java树结构stream工具类
  17. c++中无名命名空间的使用
  18. 【Python数据分析】实践编写篇2:用Python进行回归分析与相关分析
  19. 贵阳python培训价格
  20. 使用 FFmpeg 转换视频/音频格式 | 开源 免费 | 不用套壳软件

热门文章

  1. Axure8.0教程:自动带出邮箱
  2. 创意多彩配色时尚PPT幻灯片设计模板 Dianz – Business PowerPoint Template
  3. python+pywinauto+lackey实现pc端exe自动化
  4. python 2.7.11 安装pipy包管理器
  5. 新日股份2021年上半年开始亏损,称“直销业务规模出现较大缺口”
  6. Python:使用matplotlib绘制图表
  7. 卡西欧计算机储存公式,注意!CPA考试时计算器你带对了吗!
  8. 网络中查找ip冲突的服务器或台式机物理位置
  9. C语言字符串篇——常用字符串函数介绍及模拟实现
  10. 发一个无广告的解析接口