【内含实物图】一款可独立行走且支持远程对话的微型巡逻摄像头——嵌入式方案

本文主要是介绍【内含实物图】一款可独立行走且支持远程对话的微型巡逻摄像头——嵌入式方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上篇给大家分享了微型巡逻摄像头的整体硬件方案及各单元的工作原理。本篇将重点分享微型巡逻摄像头自平衡功能和移动控制功能的实现。
cam

MCU固件开发

本demo直接使用涂鸦智能SC012-WD2摄像头,因此摄像头和APP相关固件程序,并不需要开发者进行开发。开发者只需要开发底盘小车平衡运动这方面即可。

1.姿态读取

在控制平衡之前,开发者需要先获取当前平衡姿态,即先读取MPU6050数据,参考如下

void Get_Angle(uint8_t way)
{ float Accel_Y,Accel_Z,Gyro_X,Gyro_Z;Temperature=Read_Temperature();      //===读取MPU6050内置温度传感器数据,近似表示主板温度。if(way==1)                           //===DMP的读取在数据采集中断读取,严格遵循时序要求{	Read_DMP();                      //===读取加速度、角速度、倾角Angle_Balance=-Roll;             //===更新平衡倾角Gyro_Balance=-gyro[0];            //===更新平衡角速度Gyro_Turn=gyro[2];               //===更新转向角速度Acceleration_Z=accel[2];         //===更新Z轴加速度计}			else{Gyro_X=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_L);    //读取Y轴陀螺仪Gyro_Z=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_L);    //读取Z轴陀螺仪Accel_Y=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_L); //读取X轴加速度计Accel_Z=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_L); //读取Z轴加速度计if(Gyro_X>32768)  Gyro_X-=65536;                       //数据类型转换  也可通过short强制类型转换if(Gyro_Z>32768)  Gyro_Z-=65536;                       //数据类型转换if(Accel_Y>32768) Accel_Y-=65536;                      //数据类型转换if(Accel_Z>32768) Accel_Z-=65536;                      //数据类型转换Gyro_Balance=Gyro_X+Gyro_X_OFFSET;                                  //更新平衡角速度Accel_Angle=atan2(Accel_Y,Accel_Z)*180/PI;                 //计算倾角	Gyro_X=Gyro_X/16.4;                                    //陀螺仪量程转换	if(way==2)		  	Kalman_Filter(Accel_Angle,Gyro_X);//卡尔曼滤波	else if(way==3)   Yijielvbo(Accel_Angle,Gyro_X);    //互补滤波Angle_Balance=angle;                                     //更新平衡倾角Gyro_Turn=Gyro_Z+Gyro_Z_OFFSET;                                      //更新转向角速度Acceleration_Z=Accel_Z;                                //===更新Z轴加速度计	}
}
2.姿态平衡控制

获取姿态之后,开发者就可以着手控制小车保持平衡了。

在直立控制里面加入速度负反馈无法达到速度闭环的目的,而且还会破坏直立控制系统,因此在保证直立控制的优先级条件下,开发者们要把速度控制放在直立控制的前面,也就是速度控制调节的结果仅仅是改变直立控制的目标值。根据经验可知,小车的运行速度和小车的倾角是相关的。比如要提高小车向前行驶的速度,就需要增加小车向前倾斜的角度,倾斜角度加大之后,车轮在直立控制的作用下需要向前运动保持小车平衡,速度增大;如果要降低小车向前行驶的速度,就需要减小小车向前倾斜的角度,倾斜角度减小之后,车轮在直立控制的作用下向后运动保持小车平衡,速度减小。

开发者们把速度和直立两个控制器串联起来工作,其中速度控制的输出作为直立控制的输入,而直立控制的输出作为系统的输出,这其实就是一个串级控制系统。其中直立控制使用PD控制。因为编码器可能存在的噪声,为防止噪声被放大并消除系统的静差,这里速度控制使用PI控制。

3. 直立PD控制
int balance(float Angle,float Gyro)
{  float Bias;int balancePID;Bias=Angle-Angle_OFFSET;                       //===求出平衡的角度中值 和机械相关balancePID=Balance_Kp*Bias+Gyro*Balance_Kd;   //===计算平衡控制的电机PWM  PD控制   kp是P系数 kd是D系数 return balancePID;
}
4.速度PI控制
int velocity(int encoder_left,int encoder_right)
{  static float Velocity,Encoder_Least,Encoder,Movement;static float Encoder_Integral,Target_Velocity;//=============遥控前进后退部分=======================// Target_Velocity=40;                 if(Direction.Current==GO_STRAIGHT)    	Movement=-Target_Velocity/Flag_speed;	        //===前进标志位置1 else if(Direction.Current==GO_BACK)	Movement=Target_Velocity/Flag_speed;         //===后退标志位置1else  Movement=0;	//=============速度PI控制器=======================//	Encoder_Least =(encoder_left+encoder_right)-0;                   Encoder *= 0.8;		                                                //===一阶低通滤波器       Encoder += Encoder_Least*0.2;	                                    //===一阶低通滤波器    Encoder_Integral +=Encoder;                                       //===积分出位移 积分时间:10msEncoder_Integral=Encoder_Integral-Movement;                       //===接收遥控器数据,控制前进后退if(Encoder_Integral>8000)  	Encoder_Integral=8000;             //===积分限幅if(Encoder_Integral<-8000)	Encoder_Integral=-8000;              //===积分限幅	Velocity=Encoder*Velocity_Kp+Encoder_Integral*Velocity_Ki;        //===速度控制	if(Turn_Off(Angle_Balance,BAT_VOL)==1||Direction.Current==TURN_OFF)   Encoder_Integral=0;      return Velocity;
}
5.转向控制

除了保持平衡之外,小车也涉及到左右转动,因此还需要加入转向的控制,可参考如下

int turn(int encoder_left,int encoder_right,float gyro)//转向控制
{static float Turn_Target,Turn,Encoder_temp,Turn_Convert=0.9,Turn_Count; float Turn_Amplitude=30/Flag_speed,Kp=32,Kd=0; 	//=============遥控左右旋转部分=======================//if(Direction.Current==TURN_LEFT||Direction.Current==TURN_RIGHT)                      {if(++Turn_Count==1)Encoder_temp=myabs(encoder_left+encoder_right);Turn_Convert=50/Encoder_temp;if(Turn_Convert<0.6)Turn_Convert=0.6;if(Turn_Convert>3)Turn_Convert=3;}	else{Turn_Convert=0.9;Turn_Count=0;Encoder_temp=0;}			if(Direction.Current==TURN_LEFT){Turn_Target+=Turn_Convert;}else if(Direction.Current==TURN_RIGHT){Turn_Target-=Turn_Convert; }else Turn_Target=0;if(Turn_Target>Turn_Amplitude)  Turn_Target=Turn_Amplitude;    //===转向速度限幅if(Turn_Target<-Turn_Amplitude) Turn_Target=-Turn_Amplitude;if(Direction.Current==GO_STRAIGHT||Direction.Current==GO_BACK||Direction.Current==KEEP_STOP)  Kd=-1 ;        else Kd=0;   //=============转向PD控制器=======================//Turn=-Turn_Target*Kp-gyro*Kd;                 //===结合Z轴陀螺仪进行PD控制return Turn;
}
6.电机PWM控制

通过上述一系列控制计算后,开发者就得到了使小车平衡的PWM值,将该PWM值幅值给对应寄存器,就可以查看小车运动状态。

void Set_Pwm(int moto1,int moto2)
{     if(moto2>0)		{AIN2_RESET;AIN1_SET;}else 	        {AIN2_SET;AIN1_RESET;}		TIM16_PWM_Set(myabs(moto2));if(moto1>0)	{BIN1_RESET;BIN2_SET;}else        {BIN1_SET;BIN2_RESET;}TIM17_PWM_Set(myabs(moto1));
}

结语

以上就是带有可视通话功能且可以行走微型巡逻摄像头的实现方案。感兴趣的同学可以尝试动手操作,这种巡逻摄像头体积小巧可爱,可以放在家里和家人互动,也可以解决很多因空间原因无法解决的很多工作场景问题。

这篇关于【内含实物图】一款可独立行走且支持远程对话的微型巡逻摄像头——嵌入式方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/301517

相关文章

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

SpringKafka消息发布之KafkaTemplate与事务支持功能

《SpringKafka消息发布之KafkaTemplate与事务支持功能》通过本文介绍的基本用法、序列化选项、事务支持、错误处理和性能优化技术,开发者可以构建高效可靠的Kafka消息发布系统,事务支... 目录引言一、KafkaTemplate基础二、消息序列化三、事务支持机制四、错误处理与重试五、性能优

IDEA中Git版本回退的两种实现方案

《IDEA中Git版本回退的两种实现方案》作为开发者,代码版本回退是日常高频操作,IntelliJIDEA集成了强大的Git工具链,但面对reset和revert两种核心回退方案,许多开发者仍存在选择... 目录一、版本回退前置知识二、Reset方案:整体改写历史1、IDEA图形化操作(推荐)1.1、查看提

Python实现html转png的完美方案介绍

《Python实现html转png的完美方案介绍》这篇文章主要为大家详细介绍了如何使用Python实现html转png功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 1.增强稳定性与错误处理建议使用三层异常捕获结构:try: with sync_playwright(

Java使用多线程处理未知任务数的方案介绍

《Java使用多线程处理未知任务数的方案介绍》这篇文章主要为大家详细介绍了Java如何使用多线程实现处理未知任务数,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 知道任务个数,你可以定义好线程数规则,生成线程数去跑代码说明:1.虚拟线程池:使用 Executors.newVir

MySQL中闪回功能的方案讨论及实现

《MySQL中闪回功能的方案讨论及实现》Oracle有一个闪回(flashback)功能,能够用户恢复误操作的数据,这篇文章主要来和大家讨论一下MySQL中支持闪回功能的方案,有需要的可以了解下... 目录1、 闪回的目标2、 无米无炊一3、 无米无炊二4、 演示5、小结oracle有一个闪回(flashb

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式