麦克纳母轮(全向)移动机器人集群控制的Simulink/Simscape虚拟仿真平台搭建

      麦克纳姆轮是一种常见的全向移动机构,可以使机器人在平面内任意方向平移,同时可以利用差速轮车的属性实现自转,能够在狭窄且复杂多变的环境中自由运行,因而被广泛应用于竞赛机器人和特殊工业机器人场景。

       Ps:最新的BYD仰望U8也有一款是麦克纳母轮版本,但是由于运动的不稳定性和轮胎摩擦大等问题,始终不能大规模量产,B站有个up主特别搞笑,还可以用个管子去塞住仰望U8的麦克纳母轮间隙,想着开在路上这么多杂物还实在是难绷。而且由于他的运动学原理规定了他的移动速度不能过快,如果在崎岖不平的路面,可能会造成辊棒无法分解为横向和纵向两个分力,不能分解力就会造成侧移误差。而且麦轮在这种崎岖不平的路面存在较大的滚动摩擦,辊棒的磨损比汽车那种普通轮胎要更严重,继而带来的是使用成本的增加,所以麦轮只适用于低速场景和比较平滑的路面。即使满足路面平滑的要求了,汽车乘坐的舒适性也需要考虑,辊棒永远不会像轮胎那样始终与地面接触,这样就会造成颠簸震动。在实际的应用过程中我也发现,单纯靠开环位置控制和速度控制是无法实现麦轮移动机器人的精准控制的,需要添加姿态反馈和实时的位置反馈才能做到,这也是因为路面和轮子误差的问题,这也是他无法做到普及的原因。

特性和控制问题:

       但是呢,在室内狭隘的环境,他能做到不完整约束机器人做不到的事情,例如自动旋转侧移去完成所需要的任务,为此,本文基于MATLAB Simulink的Simscape模块介绍一个麦轮移动机器人具体的控制建模过程,包含麦轮的建模,运动学和动力学模型,simscape导入搭建、力接触配置、位置环和转速环PID控制策略

1. 麦克纳母轮移动机器人运动学和动力学建模

1.1 运动学方程

      运动学模型(可以参考论文或者古月居的文章,都有建模)是为了构建起电机驱动角度坐标系、机器人坐标系和大地坐标系三者之间的实时相互映射关系。 

以单个轮子为例:

当单独考虑四个轮子时:

因此,正运动学方程如下:

逆运动学方程:

1.2 动力学方程

      目前有两种方式构建动力学,一种是利用轮子的受力构建起牛顿力学方程,第二种事利用欧拉拉格朗日构建起能量的守恒方程。 

2. 麦克纳母轮移动机器人Simulink/Simscape模型建立

2.1. 单个麦克娜姆轮车的控制回路

 2.2. 底盘到轮子法兰的变换关系

2.3 传感器配置 

 2.4. 单个轮子的接触力配置

  2.5. 空间位置和姿态环PID

function [v_x1, v_y1, omega, Bias] = My_position_loop(K_dis, K_angle, p_x, p_y, angle_z, Target_x, Target_y, Target_angle_z)
v_x1 =0;
v_y1 =0;
delta_x =  Target_x-p_x;
delta_y =  Target_y-p_y;
DIF_x = delta_x * cos(angle_z) - delta_y * sin(angle_z);
DIF_y = delta_x * sin(angle_z) + delta_y * cos(angle_z);
DIF_anglez= Target_angle_z -  angle_z;
Bias = sqrt(DIF_x^2 + DIF_y^2);
Target_V = K_dis * Bias;
angle = atan2(abs(DIF_y), abs(DIF_x));
if Bias > 0.2
    temp_x = Target_V  * cos(angle);
    temp_y = Target_V  * sin(angle);
    omega = K_angle * (DIF_anglez);
    if DIF_x >=0 && DIF_y >=0
        v_x1 = temp_x;
        v_y1 = temp_y;
    elseif DIF_x >=0 && DIF_y < 0
        v_x1 = temp_x;
        v_y1 = -temp_y;
    elseif DIF_x <0 && DIF_y < 0
        v_x1 = -temp_x;
        v_y1 = -temp_y;
    elseif DIF_x <0 && DIF_y >= 0
        v_x1 = -temp_x;
        v_y1 = temp_y;
    end
else
    v_x1 = 0;
    v_y1 = 0;
    omega = K_angle * (DIF_anglez);
end
end

  2.5. 运动学速度映射 

function [wd1, wd2, wd3, wd4, flag_A, flag_B, flag_C, flag_D] = statetotheta(R, l_a, l_b, v_x, v_y, omega)
robot_state = zeros(3, 1);
J =[1, 1, (l_a + l_b);
    1,  -1, -(l_a + l_b);
    1,  -1, (l_a + l_b);
    1, 1, -(l_a + l_b)];
robot_state(1) = v_x;
robot_state(2) = v_y;
robot_state(3) = omega;
theta = (1 / R) * J * robot_state;
wd1 = theta(1);
wd2 = theta(2);
wd3 = theta(3);
wd4 = theta(4);
if wd1 >= 0
    flag_A=1;
else
    flag_A=-1;
end
if wd2 >= 0
    flag_B=1;
else
    flag_B=-1;
end
if wd3 >= 0
    flag_C=1;
else
    flag_C=-1;
end
if wd4 >= 0
    flag_D=1;
else
    flag_D=-1;
end
end

3. 电机增量式PID控制器设计

function [U, Bias] = PID(A_0, A_1, Target_A, Encoder, U_now,Last_bias)
Bias =  Target_A - Encoder;
U = U_now + A_0*(Bias - Last_bias) + A_1 * Bias;
end

3. 模型和参数配置

 包括机身的尺寸,摩擦系数,PID增益,滤波器模型,状态初值等等。

A=[1,-1.778631777824585,0.800802646665708];
B=[0.005542717210281,0.011085434420561,0.005542717210281];
l_a=(0.15);
l_b=(0.108+0.032);
l_wheel=0.108;
R_wheel=0.05;
dc=1.000000000000000e-05;
dcr=1.000000000000000e-03;
df=0.3;
dm=1000;
Ki=0.002;
Kp=0.08;
K_dis = 0.095;
K_angle = 0.45;
sf=0.50;
st=1000000;
T=0.01;
numFF=[0.00554271721028068,0.0110854344205614,0.00554271721028068];
denFF=[1,-1.77863177782459,0.800802646665708];
FF=tf(numFF,denFF);
FF.Ts=T;
Ki_angle=1;
Kp_angle=1;
x2_0 = -0.8;
y2_0 = pi+0.8;
z2_0 = 0.05;
x1_0 = -0.8;
y1_0 = -0.8+pi;
z1_0 = 0.05;
x_0 = 0;
y_0 = pi;
z_0 = 0.05;
offset_x1 = -0.8;
offset_x2 = -0.8;
offset_y1 = 0.8;
offset_y2 = -0.8;

4. 仿真效果

4.1. 轨迹曲线

 4.2. 其中一个电机的期望和实际跟踪曲线

  4.3. 空间状态期望和实际跟踪曲线

   4.3. Simscape实际仿真效果

5. 实验效果

该实验也是硕士时候和好哥们合作做的,仅供参考,任务不一样,但是核心算法都是编队规划和PID控制。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

graspnet+Astra2相机实现部署

graspnetAstra2相机实现部署 &#x1f680; 环境配置 &#x1f680; ubuntu 20.04Astra2相机cuda 11.0.1cudnn v8.9.7python 3.8.19pytorch 1.7.0numpy 1.23.5 1. graspnet的复现 具体的复现流程可以参考这篇文章&#xff1a;Ubuntu20.04下GraspNet复现流程 这里就不再详细…

C++容器之映射(std::map)

目录 1 概述2 使用实例3 接口使用3.1 construct3.2 assigns3.3 iterators3.4 capacity3.5 access3.6 insert3.7 erase3.8 swap3.9 clear3.10 emplace3.11 emplace_hint3.12 key_comp3.13 value_comp3.14 find/count3.15 upper_bound/upper_bound/equal_range3.16 get_allocator…

数据结构和算法|堆排序系列问题(一)|堆、建堆和Top-K问题

在这里不再描述大顶堆和小顶堆的含义&#xff0c;只剖析原理层面。 主要内容来自&#xff1a;Hello算法 文章目录 1.堆的实现1.1 堆的存储与表示过程1.2 访问堆顶元素1.4元素出堆 2.⭐️建堆2.1 方法一&#xff1a;借助入堆操作实现2.2 ⭐️方法二&#xff1a;通过遍历堆化实现…

Java 多线程抢红包

问题需求 一个人在群里发了1个100元的红包&#xff0c;被分成了8个&#xff0c;群里有10个人一起来抢红包&#xff0c;有抢到的金额随机分配。 红包功能需要满足哪些具体规则呢? 1、被分的人数抢到的金额之和要等于红包金额&#xff0c;不能多也不能少。 2、每个人至少抢到1元…

Ubuntu Nerfstudio安装

https://blog.csdn.net/qq_30565883/article/details/133778529 https://blog.csdn.net/weixin_52581013/article/details/137982846 https://zhuanlan.zhihu.com/p/654394767 1. 结论 因为需要安装tiny-cuda-nn&#xff0c;然而 所以我之前的在笔记本上安装就白费了&#xf…

基于python的k-means聚类分析算法,对文本、数据等进行聚类,有轮廓系数和手肘法检验

K-means算法是一种常见的聚类算法&#xff0c;用于将数据点分成不同的组&#xff08;簇&#xff09;&#xff0c;使同一组内的数据点彼此相似&#xff0c;不同组之间的数据点相对较远。以下是K-means算法的基本工作原理和步骤&#xff1a; 工作原理&#xff1a; 初始化&#x…

QT C++ QTableWidget 演示

本文演示了 QTableWidget的初始化以及单元格值改变时响应槽函数&#xff0c;打印单元格。 并且&#xff0c;最后列不一样,是combobox &#xff0c;此列的槽函数用lambda函数。 在QT6.2.4 MSVC2019 调试通过。 1.界面效果 2.头文件 #ifndef MAINWINDOW_H #define MAINWINDOW…

使用API有效率地管理Dynadot域名,进行域名邮箱的默认邮件转发设置

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…

【四数之和】python,排序+双指针

四层循环&#xff1f;&#xff08;doge) 和【三数之和】题目很类似 class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:nums.sort()#a,b,c,d四个数&#xff0c;先固定两个数&#xff0c;那就是双指针问题了&#xff0c;令ba1&#xff…

【数据结构】【C语言】堆~动画超详细解读!

目录 1 什么是堆1.1 堆的逻辑结构和物理结构1.2 堆的访问1.3 堆为什么物理结构上要用数组?1.4 堆数据上的特点 2 堆的实现2.1 堆类型定义2.2 需要实现的接口2.3 初始化堆2.4 销毁堆2.5 堆判空2.6 交换函数2.7 向上调整(小堆)2.8 向下调整(小堆)2.9 堆插入2.10 堆删除2.11 //堆…

若依解决使用https上传文件返回http路径问题

若依通过HTTPS请求进行文件上传时却返回HTTP的文件链接地址&#xff0c;主要原因是使用了 request.getRequestURL 获取链接地址。 解决办法&#xff1a; 在nginx配置文件location处加上&#xff1a;proxy_set_header X-Forwarded-Scheme $scheme; 然后代码通过request.getHea…

【跳坑日记】暴力解决Ubuntu SSH报错: Failed to start OpenBSD Secure Shell server

报错环境说明&#xff1a; 服务器环境&#xff1a;Ubuntu 20.04 错误内容 最近服务器突然报错&#xff0c;提示如下图信息&#xff1a; 搜素了各种问答&#xff0c;国内的回答大多数是用 ssh-keygen -A命令来解决&#xff0c;但最终也无法登录服务器。 最终搜索到ask ubun…

比较kube-proxy模式:iptables还是IPVS?

kube-proxy是任何 Kubernetes 部署中的关键组件。它的作用是将流向服务&#xff08;通过集群 IP 和节点端口&#xff09;的流量负载均衡到正确的后端pod。kube-proxy可以运行在三种模式之一&#xff0c;每种模式都使用不同的数据平面技术来实现&#xff1a;userspace、iptables…

go-zero 实战(3)

引入 Redis 在之前的 user 微服务中引入 redis。 1. 修改 user/internal/config/config.go package configimport ("github.com/zeromicro/go-zero/core/stores/cache""github.com/zeromicro/go-zero/zrpc" )type Config struct {zrpc.RpcServerConfMys…

代码随想录算法训练营第36期DAY35

DAY35 122买卖股票的最佳时机ii 很巧妙&#xff0c;也很难想到&#xff1a;计算每天的利润&#xff08;今天卖出&#xff0c;昨天买入的利润&#xff09;&#xff0c;只取正数相加。 class Solution {public: int maxProfit(vector<int>& prices) { int…

【机器学习300问】93、到底什么是优化器optimizer?

本文是对之前我写的梯度下降优化算法相关内容进行一次简要总结。在学习PyTorch框架的过程中&#xff0c;会遇到“优化器”&#xff08;optimizer&#xff09;这个概念。我想用通俗易懂的方式&#xff0c;说说优化器到底是个什么东西&#xff0c;并在此基础上&#xff0c;将前文…

Qt代码初识

文章目录 Qt代码初识1. Qt Hello World 程序1.1 使⽤ "按钮" 实现1.1.1 纯代码⽅式实现1.1.2 可视化操作实现 1.2 使⽤ "标签" 实现1.2.1 纯代码⽅式实现1.2.2 可视化操作实现 2. 项⽬⽂件解析2.1 .pro ⽂件解析2.2 widget.h ⽂件解析2.3 main.cpp ⽂件解析…

SwanLab入门深度学习:BERT IMDB文本情感分类

基于BERT模型的IMDB电影评论情感分类&#xff0c;是NLP经典的Hello World任务之一。 这篇文章我将带大家使用SwanLab、transformers、datasets三个开源工具&#xff0c;完成从数据集准备、代码编写、可视化训练的全过程。 观察了一下&#xff0c;中文互联网上似乎很少有能直接…

Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645)

漏洞复现环境搭建请参考 http://t.csdnimg.cn/MxmId 漏洞版本 Apache Log4j 2.8.2之前的2.x版本 漏洞验证 &#xff08;1&#xff09;开放端口4712 漏洞利用 &#xff08;1&#xff09;ysoserial工具获取 wget https://github.com/frohoff/ysoserial/releases/download/v0…

强化学习算法

从上图看出&#xff0c;强化学习可以分成价值/策略、随机策略/确定策略、在线策略/离线策略、蒙特卡洛/时间差分这四个维度。这里分析了基础算法中除了在线策略/离线策略以外的其他维度。 &#xff08;一&#xff09;基础知识 一、基础概念 重点概念&#xff1a;状态S、动作A、…