[XR806开发板试用] XR806——基于FreeRTOS下部署竞技机器人先进模糊控制器

news2024/12/24 8:26:44

前言

  • 很荣幸参与到由“极术社区和全志在线联合组织”举办的XR806开发板试用活动。
  • 本人热衷于各种的开发板的开发,同时更愿意将其实现到具体项目中。
  • 秉承以上原则,发现大家的重心都放在开发中的环境构建过程,缺少了不少实际应用场景的运用,虽然环境搭建确实痛苦。本文主要使用XR806的FreeRTOS到实际的机器人控制应用中,并实现部署模糊控制器。
  • 环境搭建本文简要略写,大家可以看社区其它优秀的文章。
  • 文章中应用到的无线控制和多维状态机两个重要的开发应用,会在后面的文章中陆续更新。

使用环境

1.本人使用window10+VMware+ubuntu 18.04 这里不多阐述
2.按照官方文档移植XR806的FreeRTOS

项目介绍

基于XR806——FreeRTOS为项目主控,部署先进模糊控制器,实现对于竞技机器人的机构控制和定位控制等。

在这里插入图片描述

渲染图
在这里插入图片描述

实物图

软硬件框架

在这里插入图片描述

控制部署

继电推理

在封装好电机驱动电流环时,实现对电机的控制,相当于建立了一种
继电特性的非线性控制,此时使用继电整定法的Z-N临界比例度法去建立模糊域。
根据以下临界系数表,整定求出模糊域。

控制器类型KPTnTvKiKd
P0.5*Kμ
PD0.8*Kμ0.12*TμKP*Tn
PI0.45*Kμ0.85*TμKP/Tn
PID0.6*Kμ0.5*Tμ0.12*TμKP/ TnKP*Tn

模糊推理

模糊推理的核心就是计算出E和EC的隶属度。同时把E和EC分为多种子集情况:负最大NB,负中NM,负小NS,零ZO,正小PS,正中PM,正大PB等七种情况。然后计算E/EC种子集的隶属度。

清晰化

进行模糊推理后,可以根据计算的隶属度,建立模糊规则表,实现对输出值的清晰化。对应到应用层的输出函数,实现控制输出。
例图:

在这里插入图片描述

FOC控制

在这里插入图片描述

仿真效果

在这里插入图片描述
在这里插入图片描述

代码实现

以下提供部分代码:

自动整定
void PID_AutoTune_Task(void)
{
		
	if(pid.AutoRegurating_Status != START) return;

	/*定义临界Tc*/
	float Tc = 0.0;
	
	static int start_cnt;  //记录最大值出现的时间
	static int end_cnt;    //记录周期结束时的时间值 

		
	static uint16_t cool_cnt = 0; 
	static uint16_t heat_cnt = 0;
		
//	pid.Autotune_Cnt ++; //计数
	
	
	if((pid.Pv_position == UP) && (pid.Pv < pid.Sv)) 
	{
		cool_cnt ++;
		if(cool_cnt >= 3) //连续三次都越过,则说明真的越过了
		{
			pid.Pv_position = DOWN; //标记当前在下方了
			pid.Zero_Across_Cnt ++;	//标记穿越一次
			cool_cnt = 0;
		}
	}
	else if((pid.Pv_position == DOWN)&&(pid.Pv > pid.Sv))//刚才在下方,现在在上方
	{
		heat_cnt++;
		if(heat_cnt >= 3) //连续三次都越过,则说明真的越过了
		{
			pid.Pv_position = UP;   //标记当前在下方了
			pid.Zero_Across_Cnt ++;	//标记穿越一次
			heat_cnt = 0;
		}		
	}
	
	/*****************开始计算强行振荡的周期****************************/	
	if((pid.Zero_Across_Cnt == 2)&&(start_cnt == 0))
	{
		start_cnt = pid.Autotune_Cnt;
		printf("start_time = %d\r\n", start_cnt);
	}else if((pid.Zero_Across_Cnt == 4)&&(end_cnt == 0))
	{
		end_cnt = pid.Autotune_Cnt;
		printf("start_time = %d\r\n", end_cnt);
	}
		
	if(pid.Zero_Across_Cnt == 4)
	{	
		/*计算一个震荡周期的时间*/
		if(start_cnt > end_cnt)
			Tc = (start_cnt-end_cnt)/2;  
		else
			Tc = (end_cnt-start_cnt)/2;  
		
		/*计算Kp,Ti和Td*/
		pid.Kp = 0.6*pid.Kp;
		pid.Ti = Tc*0.5;   
		pid.Td = Tc*0.12;  
		
		/*PID参数整定完成,将各项数据清0*/
		heat_cnt 	= 0;
		cool_cnt 	= 0;	
		pid.Autotune_Cnt = 0;
		start_cnt	= 0;
		end_cnt		= 0;	
		pid.SEk   = 0;
		
		pid.Zero_Across_Cnt 			= 0;					
		pid.AutoRegurating_EN 		= OFF;
		pid.AutoRegurating_Status = OVER; //开始运行使用新的参数后的PID算法

		pid.Sv   = pid.BKSv;    
	}
}	
模糊控制
/*模糊规则表*/
int KpRule[7][7]= {  
	  /*NB, NM,  NS, ZO, PS, PM, PB -EC*/
		{1,   1,   1,  1,  1,  1,  1}, //NB 0~-10
		{0,   0,   0,  1,  2,  3,  4}, //NM 0~10
		{0,   0,   0,  1,  2,  3,  4}, //NS 10~20   
		{0,   0,   1,  1,  2,  3,  4}, //20~30
		{1,   1,   1,  1,  2,  3,  4}, //30~40
		{1,   1,   1,  1,  2,  3,  4}, //40 ~50
    {6,   6,   6,  6,  6,  6,  6}, //50~60       
};
static float fuzzy_kp(float err, float errchange) 
{                 
  volatile float Kp_calcu;  
  volatile uint8_t num,pe,pec;   
 
  volatile float eFuzzy[2]={0.0,0.0};      //隶属于误差E的隶属程度  
  volatile float ecFuzzy[2]={0.0,0.0};     //隶属于误差变化率EC的隶属程度  
 
  float KpFuzzy[7]={0.0,0.0,0.0,0.0,0.0,0.0,0.0}; //隶属于Kp的隶属程度  
	
  /*****误差E隶属函数描述*****/ 
  if(err<eRule[0])         
  {   
		eFuzzy[0] =1.0;    
		pe = 0;  
  }  
  else if(eRule[0]<=err && err<eRule[1])  
  {   
		eFuzzy[0] = (eRule[1]-err)/(eRule[1]-eRule[0]);   
		pe = 0;  
  }  
  else if(eRule[1]<=err && err<eRule[2])  
  {   
		eFuzzy[0] = (eRule[2] -err)/(eRule[2]-eRule[1]);   
		pe = 1;  
  }  
  else if(eRule[2]<=err && err<eRule[3])  
  { 
		eFuzzy[0] = (eRule[3] -err)/(eRule[3]-eRule[2]);   
		pe = 2;  
  }     
  else if(eRule[3]<=err && err<eRule[4])     
  {   
		eFuzzy[0] = (eRule[4]-err)/(eRule[4]-eRule[3]);         
		pe = 3;     
  }  
  else if(eRule[4]<=err && err<eRule[5])  
  {   
		eFuzzy[0] = (eRule[5]-err)/(eRule[5]-eRule[4]);   
		pe = 4;  
  }  
  else if(eRule[5]<=err && err<eRule[6])  
  {   
			eFuzzy[0] = (eRule[6]-err)/(eRule[6]-eRule[5]);   
			pe = 5;  
  }  
  else  
  {   
		eFuzzy[0] =	0.0;   
		pe =	6;  
  }    
  eFuzzy[1] =1.0 - eFuzzy[0];  
  /*****误差变化率EC隶属函数描述*****/       
  if(errchange<ecRule[0])         
  {   
    ecFuzzy[0] =1.0;   
		pec = 0;  
  }  
  else if(ecRule[0]<=errchange && errchange<ecRule[1])  
  {   
		ecFuzzy[0] = (ecRule[1] - errchange)/(ecRule[1]-ecRule[0]);   
		pec = 0 ;  
  }  
  else if(ecRule[1]<=errchange && errchange<ecRule[2])  
  {   
		ecFuzzy[0] = (ecRule[2] - errchange)/(ecRule[2]-ecRule[1]);   
		pec = 1;  
  }  
  else if(ecRule[2]<=errchange && errchange<ecRule[3])  
  {   
		ecFuzzy[0] = (ecRule[3] - errchange)/(ecRule[3]-ecRule[2]);   
		pec = 2 ;  
  } 
  else if(ecRule[3]<=errchange && errchange<ecRule[4])     
  {   
		ecFuzzy[0] = (ecRule[4]-errchange)/(ecRule[4]-ecRule[3]);         
		pec=3;     
  }  
  else if(ecRule[4]<=errchange && errchange<ecRule[5])     
  {   
		ecFuzzy[0] = (ecRule[5]-errchange)/(ecRule[5]-ecRule[4]);         
		pec=4;     
  }  
  else if(ecRule[5]<=errchange && errchange<ecRule[6])     
  {   
		ecFuzzy[0] = (ecRule[6]-errchange)/(ecRule[6]-ecRule[5]);         
		pec=5;     
  }  
  else  
  {   
		ecFuzzy[0] =0.0;   
		pec = 5;  
  }  
  ecFuzzy[1] = 1.0 - ecFuzzy[0];   
  /*********查询模糊规则表*********/     
  num =	KpRule[pe][pec];  
  KpFuzzy[num] += (eFuzzy[0]*ecFuzzy[0]); 
  num =	KpRule[pe][pec+1];   
  KpFuzzy[num] += (eFuzzy[0]*ecFuzzy[1]);  
  num =KpRule[pe+1][pec];  
  KpFuzzy[num] += (eFuzzy[1]*ecFuzzy[0]);  	
  num =	KpRule[pe+1][pec+1];  
  KpFuzzy[num] += (eFuzzy[1]*ecFuzzy[1]); 
  /*********加权平均法解模糊*********/    
  Kp_calcu	=	KpFuzzy[0]*kpRule[0] +KpFuzzy[1]*kpRule[1]+ \
							KpFuzzy[2]*kpRule[2] +KpFuzzy[3]*kpRule[3]+ \
							KpFuzzy[4]*kpRule[4] +KpFuzzy[5]*kpRule[5]+ \
							+KpFuzzy[6]*kpRule[6];   

	printf(" %f,%f,%d,%d,kp = %f\r\n", err, errchange, pe, pec, Kp_calcu);
  return(Kp_calcu); 
} 

实物展示

无刷电机控制

https://www.bilibili.com/video/BV1FN4y1C7fY/?aid=874778769&cid=1302701130&page=null

整体定位控制

https://www.bilibili.com/video/BV1NN411t7Fy/?aid=492262076&cid=1302702003&page=null

以上,就是本文分享的全部内容了,感谢各位

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1327264.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安卓好用的python编辑器,安卓平台python编辑器

本篇文章给大家谈谈安卓上好用的python编辑软件有哪些&#xff0c;以及安卓上好用的python编辑软件推荐&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 1. 简介 Thonny是基于python内置图形库tkinter开发出来的支持多平台(windows,Mac,Linux)的python IDE&am…

Dubbo的学习笔记

目录 架构 zookeeper的简单介绍 简单案例 Dubbo-admin的简单使用 Dubbo高级特性 序列化 地址缓存 超时与重试 多版本 负载均衡 集群容错 服务降级 Dubbo是阿里巴巴开源的一个高性能、轻量级RPC框架 架构 provider&#xff1a;暴露服务的服务提供方container&#x…

React学习计划-React16--React基础(三)收集表单数据、高阶函数柯里化、类的复习

1. 收集表单数据 包含表单的组件分类 受控组件——页面中所有输入类的DOM,随着输入&#xff0c;把值存维护在状态里&#xff0c;需要用的时候去状态里取值&#xff08;推荐&#xff0c;避免了过渡使用ref&#xff09;非受控组件——页面中所有输入类的DOM&#xff0c;现用现取…

【Vulnhub 靶场】【ContainMe: 1】【简单-中等】【20210729】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/containme-1,729/ 靶场下载&#xff1a;https://download.vulnhub.com/containme/THM-ContainMe-v4.ova 靶场难度&#xff1a;简单 - 中等 发布日期&#xff1a;2021年07月29日 文件大小&#xff1a;2.2 GB 靶…

文件的查看与管理

目录 一、命令之-----cat &#xff08;一&#xff09;查看文本文件内容 &#xff08;二&#xff09;合并文件内容 &#xff08;三&#xff09;创建文件 &#xff08;四&#xff09;追加内容到文件 二、管道符的作用 三、分页显示 &#xff08;一&#xff09;命令之…

Postgresql源码(118)elog/ereport报错跳转功能分析

1 日志接口 elog.c完成PG中日志的生产、记录工作&#xff0c;对外常用接口如下&#xff1a; 1.1 最常用的ereport和elog ereport(ERROR,(errcode(ERRCODE_UNDEFINED_TABLE),errmsg("relation \"%s\" does not exist",relation->relname)));elog(ERRO…

重塑数字生产力体系,生成式AI将开启云计算未来新十年?

科技云报道原创。 今天我们正身处一个历史的洪流&#xff0c;一个巨变的十字路口。生成式AI让人工智能技术完全破圈&#xff0c;带来了机器学习被大规模采用的历史转折点。 它掀起的新一轮科技革命&#xff0c;远超出我们今天的想象&#xff0c;这意味着一个巨大的历史机遇正…

Hbase的安装配置

注&#xff1a;本文默认已经完成hadoop的下载以及环境配置 1.上传zookeeper和hbase压缩包到指令路径并且解压 (理论上讲&#xff0c;hbase其实内置了zookeeper&#xff0c;我们也可以不另外下载&#xff0c;另外下载的目的在于减少组件间依赖性) cd /home mkir hbase cd /hom…

IDEA 黑色主题很难看到鼠标

“控制面板”—搜索“鼠标”关键字—选择“更改鼠标设置” 参考&#xff1a; IDEA 黑色主题很难看到鼠标

ansible的脚本-----playbook剧本

ansible的脚本-----playbook剧本 playbook组成部分&#xff1a; 1、tasks任务&#xff1a;包含要在目标主机上执行的操作&#xff0c;使用模块定义这些操作。每个任务都是一个模块的调用 2、variables变量&#xff1a;存储和传递数据&#xff0c;变量可以自定义&#xff0c;…

WeakMap 和 WeakSet:解决内存泄漏避免循环引用(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

React组件状态管理

React组件的状态管理是一个很重要的内容。从字面来理解&#xff0c;按钮是否可单击、图片是否显示等&#xff0c;这些都是状态。广义来讲&#xff0c;React组件的状态还1包括传入React的数据&#xff0c;例如某个组件要展示列表&#xff0c;列表的数据也是该组件的状态。总之&a…

Dynamic Coarse-to-Fine Learning for Oriented Tiny Object Detection(CVPR2023待补)

文章目录 BeginningAbstract挑战方法成果 Introduction引出问题早期的work及存在的问题近期的work及存在的问题our workContribution Related Work&#xff08;paper for me&#xff09;Oriented Object DetectionPrior for Oriented ObjectsLabel Assignment Tiny Object Dete…

【算法】算法题-20231221

这里写目录标题 一、830. 较大分组的位置二、657. 机器人能否返回原点三、771. 宝石与石头 一、830. 较大分组的位置 在一个由小写字母构成的字符串 s 中&#xff0c;包含由一些连续的相同字符所构成的分组。 例如&#xff0c;在字符串 s "abbxxxxzyy"中&#xff0…

【XML】TinyXML 详解

1、简介 优点&#xff1a; TinyXML 是一个简单、小型的 C XML 解析器&#xff0c;可以轻松集成到项目中。 TinyXML 解析 XML 文档&#xff0c;并根据该文档构建可读取、修改和保存的文档对象模型 (DOM) TinyXML 是在 ZLib 许可下发布的&#xff0c;因此可以在开源或商业代码中…

【SQL题目】连续日期的判断

【1.查询至少连续3天下单的用户】 思路1&#xff08;使用lead&#xff09;&#xff1a; distinct user_id,create_date去重&#xff0c;确保每个用户每天只有一条访问记录lead(create_date,2,‘9999-12-31’) over(partition by user_id order by create_date)根据用户分区&am…

模型实战(18)之C++ - tensorRT部署GAN模型实现人脸超分辨重建

模型实战(18)之C++ - tensorRT部署GAN模型实现人脸超分辨重建 一个实现人脸超分辨率重建的demo支持StyleGAN: GPEN or GFPGAN通过C++ - tensorrt 快速部署,推理速度每帧 在RTX3090上5.5ms+,RTX3050上10ms+下边是实现效果(图片来源于网络search,如若侵权,联系删除) 下边…

AI Native工程化:百度App AI互动技术实践

作者 | GodStart 导读 随着AI浪潮的兴起&#xff0c;越来越多的应用都在利用大模型重构业务形态&#xff0c;在设计和优化Prompt的过程中&#xff0c;我们发现整个Prompt测评和优化周期非常长&#xff0c;因此&#xff0c;我们提出了一种Prompt生成、评估与迭代的一体化解决方案…

YashanDB个人版体验总结

前言 YashanDB数据库具有多项功能特性。首先&#xff0c;它是一个分布式数据库&#xff0c;支持水平扩展&#xff0c;能够将数据分散到多个节点上&#xff0c;从而提高系统的可靠性和性能。其次&#xff0c;YashanDB数据库具备高可用性&#xff0c;支持主从复制和自动故障转移…

竞赛保研 基于Django与深度学习的股票预测系统

文章目录 0 前言1 课题背景2 实现效果3 Django框架4 数据整理5 模型准备和训练6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于Django与深度学习的股票预测系统 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff…