用MATLAB仿真仿射队形变换(affine formation maneuver)

2023-05-16

文章目录

  • 写在前面
  • 如何仿真静态编队控制
    • 构建stress matrix
    • MATLAB求解LMI问题
    • 静态编队控制源代码
  • 如何仿真时变轨迹和队形变换
    • 轨迹生成
    • 时变leader控制律
    • 时变轨迹和队形变换源代码

写在前面

原论文标题:Affine Formation Maneuver Control of Multiagent Systems.

之前的文章讲了赵世钰的仿射编队控制原理1,进行了相关理论分析,发出来之后有不少同学私信问我如何复现他的论文。于是我现在再写这篇文章填个坑,把如何用MATLAB复现的思路讲一下,给之前的文章做个结尾。

如何仿真静态编队控制

读完赵的论文后,相信大家对控制算法已经掌握了,毕竟在形式上和一般的consensus极其相似。但是相比拉普拉斯矩阵,stress matrix的构建更加麻烦。下面详细讲一下在MATLAB中如何构建stress matrix。

我们首先给出一个任意的连通图,由关联矩阵 D D D定义。

% incidence matrix
D = [1,-1,0,0,0,0,0,0,0,-1,0,1;
    -1,0,0,0,0,0,1,-1,0,0,0,0;
    0,1,-1,0,0,0,0,0,1,0,0,0;
    0,0,0,0,0,1,-1,0,0,1,-1,0;
    0,0,1,-1,0,0,0,0,0,0,1,-1;
    0,0,0,0,1,-1,0,0,-1,0,0,0;
    0,0,0,1,-1,0,0,1,0,0,0,0];
L = D*D';
H = D';

为了确定stress matrix Ω \Omega Ω,还需要再给出期望的队形位置 r r r。为了简单起见,代码中r代表 P ( r ) P(r) P(r)P代表 P ˉ ( r ) \bar P(r) Pˉ(r)

%% dimensions
[n,m] = size(D);
d = 2;

% r represents P(r)
r = [2,0;
    1,1;
    1,-1;
    0,1;
    0,-1;
    -1,1;
    -1,-1];
    
% P represents \bar P(r)
P = [r,ones(n,1)];

构建stress matrix

接下来,我们按照论文VII-A的方法构建stress matrix Ω \Omega Ω

第一步,创建 E E E矩阵,使得 E ω = 0 E\omega=0 Eω=0,其中 ω ∈ R m \omega\in\mathbb R^m ωRm为每条边对应的权重,各元素与 D D D的列对应。

由于 Ω = H T diag ⁡ ( ω ) H \Omega=H^T\operatorname{diag}(\omega)H Ω=HTdiag(ω)H Ω P ˉ ( r ) = 0 \Omega \bar P(r)=0 ΩPˉ(r)=0 P ˉ T ( r ) H T diag ⁡ ( ω ) H = P ˉ T ( r ) H T diag ⁡ ( ω ) [ h 1 , ⋯   , h n ] = 0 \bar P^T(r)H^T\operatorname{diag}(\omega)H=\bar P^T(r)H^T\operatorname{diag}(\omega)[h_1,\cdots,h_n]=0 PˉT(r)HTdiag(ω)H=PˉT(r)HTdiag(ω)[h1,,hn]=0。因为 diag ⁡ ( ω ) h i = diag ⁡ ( h i ) ω \operatorname{diag}(\omega)h_i=\operatorname{diag}(h_i)\omega diag(ω)hi=diag(hi)ω,所以 P ˉ T ( r ) H T diag ⁡ ( h i ) ω = 0 , ∀ i = 1 , ⋯   , n \bar P^T(r)H^T\operatorname{diag}(h_i)\omega=0,\forall i=1,\cdots,n PˉT(r)HTdiag(hi)ω=0,i=1,,n

E = [];
for i=1:n 
    E = [E;P'*H'*diag(H(:,i))];
end

定义 Z = [ z 1 , ⋯   , z q ] ∈ null ⁡ ( E ) Z=[z_1,\cdots,z_q]\in\operatorname{null}(E) Z=[z1,,zq]null(E),则 ω = Z c \omega=Zc ω=Zc,其中 c ∈ R q c\in\mathbb R^q cRq是系数。

z = null(E);
c = zeros(size(z,2),1);

第二步,求系数 c c c。对 P ˉ ( r ) \bar P(r) Pˉ(r)奇异值分解, P ˉ ( r ) = U Σ V T \bar P(r)=U\Sigma V^T Pˉ(r)=UΣVT。令 U = [ U 1 , U 2 ] U=[U_1,U_2] U=[U1,U2],其中 U 1 U_1 U1包含前 d + 1 d+1 d+1列。因为 rank ⁡ ( P ˉ ( r ) ) = d + 1 \operatorname{rank}(\bar P(r))=d+1 rank(Pˉ(r))=d+1 U 1 U_1 U1 P ˉ ( r ) \bar P(r) Pˉ(r)的列空间, U 2 U_2 U2 P ˉ T ( r ) \bar P^T(r) PˉT(r)的零空间,所以 U 1 T Ω U 1 = 0 U_1^T\Omega U_1=0 U1TΩU1=0 U 2 T Ω U 2 > 0 U_2^T\Omega U_2>0 U2TΩU2>0。将 ω = Z c \omega=Zc ω=Zc代入, U 2 T H T diag ⁡ ( Z c ) H U 2 = ∑ i = 1 q c i U 2 T H T diag ⁡ ( z i ) H U 2 > 0 U_2^TH^T\operatorname{diag}(Zc)HU_2=\sum_{i=1}^q c_iU_2^TH^T\operatorname{diag}(z_i)HU_2>0 U2THTdiag(Zc)HU2=i=1qciU2THTdiag(zi)HU2>0

% svd
[U,S,V] = svd(P);
U1 = U(:,1:d+1);
U2 = U(:,d+2:end);
% calculate M
for i=1:size(z,2)
	M{i} = U2'*H'*diag(z(:,i))*H*U2;
end

M i = U 2 T H T diag ⁡ ( z i ) H U 2 M_i=U_2^TH^T\operatorname{diag}(z_i)HU_2 Mi=U2THTdiag(zi)HU2,则只需求解LMI问题: ∑ i = 1 q c i M i > 0 \sum_{i=1}^q c_iM_i>0 i=1qciMi>0

MATLAB求解LMI问题

MATLAB求解LMI问题步骤如下:

  • 初始化;
% Initialization
setlmis([]);
  • 确定待定变量和不等式;

lmivar(type,struct)指定变量为未知变量,type=1表示变量为对称矩阵,struct=[1,0]表示只有1个block,且为scalar。

lmiterm(termid,A,B,flag)指定相应的不等式,termid=[-1,1,1,c(i)],第一项表示第1个不等式,负号表示 > 0 >0 >0,第二、三项表示处于哪个位置,如(1,1)表示处于第1行第1列,第四项表示该不等式对应哪一个未知变量。这里令 c = [ c 1 , ⋯   , c q ] c=[c_1,\cdots,c_q] c=[c1,,cq],不等式为 c 1 M 1 + ⋯ + c q M q > 0 c_1M_1+\cdots+c_qM_q>0 c1M1++cqMq>0lmiterm定义每一个 c i M i c_iM_i ciMi,不等式号为1,位置都为(1,1)。

for i=1:size(z,2)
	% Defining the Decision Variables
    c(i) = lmivar(1,[1,0]);
    % Define the LMIs one by one
    lmiterm([-1,1,1,c(i)],1,M{i});
end
  • 建立模型和求解。

getlmis得到对应LMI问题模型,feasp求解LMI问题。

lmi = getlmis;
[~,csol] = feasp(lmi);
for i=1:size(null_E,2)
    c(i) = dec2mat(lmi,csol,c(i));
end
c = c/norm(c);
cM = [M{:}]*kron(c,eye(size(M{1},2)));
% check if cM>0

求解出 c c c之后即可得到 Ω = H T Z c H \Omega=H^TZcH Ω=HTZcH

w =  z*c;
Omega = H'*diag(w)*H;

静态编队控制源代码

静态编队控制源代码见我的GitHub,见项目paper-simulation。运行Zhao2018Affine文件夹下的文件affine_formation.m,即可得到下面的仿真结果。

如何仿真时变轨迹和队形变换

时变队形有两个难点,一个是轨迹生成,另一个是时变leader控制律。

轨迹生成

轨迹生成部分我是对给定队形做仿射变换,即 x r = A r + b x_r=Ar+b xr=Ar+b

b b b对应代码里的via A A A对应代码里的T_1*T_2,要对 A , b A,b A,b的每一个元素生成轨迹,最后再合并成 x r x_r xr

via = [0,0;
    5,0;
    10,0;
    10,-5;
    10,-10;
    5,-10;
    0,-10];
for j=1:size(via,1)
    if ~mod(j,2)
        if j==4
            T1 = diag([0.1,1]);
        else
            T1 = diag([1,0.1]);
        end
    else
        T1 = eye(2);
    end
    T2 = rot2(-pi/2*floor((j-1)/2));
    ra(:,:,j) = r*T2'*T1'+via(j,:);
    qvia(j,:) = [vec(T1*T2)',via(j,:)];
    for i=1:m
        plot(ra(edge(:,i),1,j),ra(edge(:,i),2,j),'k','linewidth',2); hold on
    end
end
[qr,dqr,ddqr,tr] = mstraj_(qvia,ones(1,6),0.1,0.2);
A = reshape(qr(1,1:4)',[2,2]);
b = qr(1,5:6)';
xr = r*A'+b';

时变leader控制律

写这个控制律其实不难,只是有点麻烦,不能像拉普拉斯矩阵一样写成矩阵形式,所以只能一条边一条边的求和。

gamma = diag(Omega);
% follower 4:n
for i=4:n
    err_sum = [0,0];
    edge_ind = find(D(i,:)~=0);
    for k=edge_ind
        node_ind = find(D(:,k)~=0);
        j = node_ind(node_ind~=i);
        err_sum = err_sum+z(k)*(x(i,:)-x(j,:)-dx(j,:));
    end
    dx(i,:) = -1/gamma(i)*err_sum;
end
% leader 1:3
dx(1:3,:) = dxr(1:3,:)-alpha*(x(1:3,:)-xr(1:3,:));

时变轨迹和队形变换源代码

时变轨迹和队形变换源代码见我的GitHub,见项目paper-simulation。运行Zhao2018Affine文件夹下的文件affine_maneuver.m,即可得到下面的仿真结果。


  1. Zhao, S. (2018). Affine Formation Maneuver Control of Multiagent Systems. IEEE Transactions on Automatic Control, 63(12), 4140–4155. https://doi.org/10.1109/TAC.2018.2798805 ↩︎

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用MATLAB仿真仿射队形变换(affine formation maneuver) 的相关文章

  • Matlab:条形图中缺少标签

    使用 Matlab 2012 和 2013 我发现设置XTickLabel on a bar图表最多只能使用 15 个柱 如果条形较多 则标签会丢失 如下所示 绘制 15 个条形图 N 15 x 1 N labels num2str x d
  • Numpy 相当于 MATLAB 的 hist [重复]

    这个问题在这里已经有答案了 由于某种原因 Numpy 的 hist 总是返回比 MATLAB 的 hist 少 1 个 bin 例如在 MATLAB 中 x 1 2 2 2 1 4 4 2 3 3 3 3 Rep Val hist x un
  • 在matlab中,如何读取python pickle文件?

    在 python 中 我生成了一个 p 数据文件 pickle dump allData open myallData p wb 现在我想在Matlab中读取myallData p 我的Matlab安装在Windows 8下 其中没有Pyt
  • Ilnumerics Ilpanel 在 winform 中编译成 dll 并加载到 matlab 时不激活

    我想将 Visual studio 2012 中用 C 编写的 winform 编译为 dll 然后将其加载到 matlab 2013a 中 然后 我想使用 matlab net 接口与 winform 进行交互 侦听其事件并通过一组预定义
  • 将 Matlab 数组移植到 C/C++

    我正在将 matlab 程序移植到 C C 我有几个问题 但最重要的问题之一是 Matlab 将任何维度的数组都视为相同 假设我们有一个这样的函数 function result f A B C result A 2 B C A B and
  • 在 MATLAB 中绘图后恢复轴

    从文本文件绘制多种方法的输出后 未显示轴的右侧和上侧 我需要拥有它们并将它们加粗 就像当前的轴一样 绘制的数据来自存储每种方法数据的文件 每个数据文件都是一个 256x2 文件 包含 0 1 之间的值 第一列是精度 第二列是召回率 figu
  • 通过 cuFFT 进行逆 FFT 缩放

    每当我使用 cuFFT 绘制程序获得的值并将结果与 Matlab 的结果进行比较时 我都会得到相同形状的图形 并且最大值和最小值位于相同的点 然而 cuFFT 得到的值比 Matlab 得到的值大得多 Matlab代码是 fs 1000 s
  • MATLAB:将当前文件夹设置为脚本位置

    我在不同的文件夹中有一些脚本和数据 我使用addpath和相对路径经常 我的问题是 只有当我的当前文件夹是我执行的脚本所在的位置时 这才有效 例如 如果我执行添加路径 X 的脚本 A 然后执行位于路径 X 中的脚本 B 则 Matlab 不
  • 图像梯度角计算

    我实际上是按照论文的说明进行操作的 输入应该是二进制 边缘 图像 输出应该是一个新图像 并根据论文中的说明进行了修改 我对指令的理解是 获取边缘图像的梯度图像并对其进行修改 并使用修改后的梯度创建一个新图像 因此 在 MATLAB Open
  • Deploytool for MATLAB R2013b 不起作用,发生了什么变化?

    多年来我一直在使用集成deploytool为我的同事创建易于分发的 exe 文件 我几天前安装了R2013b 但无法使用deploytool不再了 尝试打包时的日志文件给出了以下内容 ant
  • 更新:随机将行添加到矩阵中,但遵循严格的规则

    以下是一个更大的矩阵的一部分 0 1 0000 1 0000 77 0000 100 0000 0 0 2500 0 1 0000 1 0000 72 0000 100 0000 0 2500 0 2500 0 1 0000 1 0000
  • 优先连接,Matlab 中的复杂网络

    大家好 我现在正在 MATLAB 中研究优先附件模型 在理解以下内容时遇到一些困难 假设我一开始有 4 个节点 连接如下 time 0 1 lt gt 2 3 lt gt 4 在下一个时间步骤中 我添加一个节点和 4 个连接 然后添加另一个
  • MATLAB 中的逻辑数组与数值数组

    我正在比较两个二进制数组 我有一个数组 其中值可以是一或零 如果值相同则为 1 如果不同则为零 请注意 我正在做检查之外的其他事情 因此我们不需要进入矢量化或代码的性质 在 MATLAB 中使用数值数组和逻辑数组哪个更有效 Logical
  • 在 Python 上显示 Matlab mat 文件中的图像

    我目前正在尝试显示从此下载的 Mat 文件中的图像site http www rctn org bruno sparsenet 这是一个 mat 文件 所以我尝试使用 scipy io loadmat 函数加载它 但我似乎无法绘制图像 我究
  • matlab中优先级队列的实现方法

    matlab中有没有提供minpriorityqueue功能的库 import java util PriorityQueue import java util public class MyQueue Comparator
  • 计算给出数组中最小标准差的子集

    让我们有一个大小的向量N 例如 x rand N 1 我想计算长度子集的最小标准差K在向量中 When N and K很小 很容易找到最好的子集 因为我可以使用nchoosek N K 枚举所有可能的子集 但是当值N and K比我们说的要
  • 使用网络计算机进行 Matlab 并行处理

    我熟悉matlabpool and parfor用法 但我仍然需要加快计算速度 我的 1GB 网络中有一台功能更强大的计算机 两台计算机都有 R2010b 并且具有相同的代码和路径 使用两台计算机进行并行计算的最简单方法是什么 我今天使用的
  • MATLAB 符号替换

    我知道在 MATLAB 中如果声明了 syms x y f x 2 y 2 grad gradient f 然后grad会存储值 2 x 2 y 如果我想评估梯度 2 2 I use subs f x y 2 2 这返回 4 4 我正在编写
  • Matlab的uicontrol在Octave中的实现?

    我正在尝试在 Octave 中运行我们实验室中使用的图形程序的 m Matlab 代码 Octave 告诉我代码中使用的函数 uicontrol 没有定义 经过一番搜索 我发现 JHandles 包有一个 uicontrol GUI 功能的
  • 如何从列中创建对称矩阵?

    例如 我想转动以下列 90 175 600 650 655 660 代入矩阵 90 175 600 650 655 660 175 600 650 655 660 655 600 650 655 660 655 650 650 655 66

随机推荐

  • 面试题:单片机裸机和RTOS开发过程中,如何保证全局变量在中断和主循环中读写的正确性

    这个面试题时考察的关键字volatile 临界区 xff0c 原子操作和锁的概念 xff0c 因此首先需要搞清楚这几个知识点以及使用方法 1 关键字volatile 关键字volatile时告诉编译器 xff0c 被关键字volatile修
  • 丰润达为天津艺洲彭泽大酒店打造酒店安防监控改造项目

    衡量一个酒店是否安全的一个很重要的标准 xff0c 就是酒店的各个角落是否都布有监控设备 要知道 xff0c 很多受害人被侵害 xff0c 都是发生在监控看不到的角落 可以说监控就像是一双锐利的眼睛 xff0c 时时注视着坏蛋 xff0c
  • 对不起,这个官司我不服!数据隐私保护是阿里云的生命线

    摘要 xff1a 对阿里云来说 xff0c 保护用户数据隐私一直是我们坚守的生命线 在这次事件处理中 xff0c 保护数据隐私是我们的第一原则 阿里云认为 xff0c 作为云服务器提供商 xff0c 阿里云无权审查任何用户数据 只有收到司法
  • CentOS中添加Swap

    1 检查 Swap 空间在设置 Swap 文件之前 xff0c 有必要先检查一下系统里有没有既存的 Swap 文件 运行以下命令 xff1a 1 swapon s 如果返回的信息概要是空的 xff0c 则表示 Swap 文件不存在 2 检查
  • 优秀程序员的故事

    A君默默的工作了3年 xff0c 从项目初立 xff0c 到遍地开花 工作不忙 xff0c 工资没长 新领导来了 xff0c 下个版本重新开发 xff0c A君继续维护老版本 新招了一批人 xff0c 加班加点干了半年多 直到版本发布 xf
  • android studio 控制台输出乱码

    问题 android studio 控制台输出乱码 详细问题 解决方案 双击Shift 全局查找快捷键 xff0c 输入vmoption xff0c 选择Edit Custom CM Options 即 如果之前没有配置过 xff0c 会弹
  • Linux下使用VSCode,GCC,OpenOCD实现STM32一键编译烧录调试(CMake篇)

    Linux下使用VSCode开发STM32 xff08 二 xff09 一 开发工具安装二 测试工程简介三 CMake工具1 CMakeLists txt2 生成Makefile3 make编译 四 json脚本实现一键编译烧录调试1 la
  • CMake Error at cmake/OpenCVDetectCXXCompiler.cmake:85 (list)

    Ubuntu 18 4 安装opencv 2 4 10时遇到如下问题 xff1a CMake Error at cmake OpenCVDetectCXXCompiler cmake 85 list list GET given empty
  • Camera-IMU标定工具Kalibr的编译

    关于catkin make过程中下载suitesparse过久甚至失败的问题 xff1a 在安装kalibr时的suitesprse库时 xff0c 对应的cmakelists中会通过wget 下载压缩包 xff0c 若无法下载则整个kal
  • 远程桌面,RDP文件密码加密、解密算法(C#)

    背景 xff1a 由于项目需要 xff0c 使用RDP文件来远程登录 xff0c 需要实现点击rdp文件就可以自动连接远程桌面 xff0c 并且实现自动登录功能 xff01 自动登录 xff01 自动登录 xff01 自动登录 xff1a
  • 解决apt install存在依赖关系导致无法安装成功的办法

    安装aptitude xff0c 使用aptitude进行安装会自动给出解决方案 sudo apt get install aptitude sudo aptitude install XXX
  • cubemx在使用freertos的时候为何推荐使用除systick以外的timebase

    摘要 第一次使用stm32cubemx 在配置freertos后生成代码时会提示 When FreeRTOS is used It is strongly recommended to use a HAL timebase source o
  • 状态机编程 (一) 状态机相关概念

    基本概念 状态机编程 xff0c 又称事件驱动型编程 事件驱动程序需要一系列的精细粒度的事件处理函数来处理事件 这些事件函数必须处理的很快并返回主事件循环 所以其非常依赖于通过使用静态变量维护在从一个事件驱动函数转换到下一个执行函数时的执行
  • 后端状态估计-卡尔曼滤波器理解+扩展-SLAM14讲笔记(六)

    文章目录 系列文章目录前言一 pandas是什么 xff1f 二 使用步骤 1 引入库2 读入数据 状态估计的概率解释 xff1a 位姿x和路标y服从某种概率分布 xff0c 目的是通过某些运动数据u xff08 比如惯性测量传感器IMU输
  • OpenCV笔记.1 - OpenCV的编译和安装

    OpenCV的编译和安装 想要使用OpenCV进行图像的处理和开发 xff0c 就需要先对OpenCV库进行编译 虽然在Windows下已经有了现成的OpenCV库 xff0c 但是由于官方提供的库缺少一些关键的功能 xff08 例如Ope
  • Git中stash和stage的差别

    对于初学者来说 xff0c git中stash和stage两个命令的单词有些相似 xff0c 有可能会弄混 其实二者是两个完全不同的概念 1 stash是git中的一个命令 git stash的作用是把工作区 必须是工作区中已经被git追踪
  • 用matlab和RTB做二连杆机械臂动力学建模

    文章目录 写在前面二连杆机械臂RTB建模仿真与验证源代码 写在前面 本文使用的工具为matlab以及Peter Corke的RTB Robotics Toolbox 基于RTB 10 3 1版本 xff0c 我写了RTE Robotics
  • 机械臂协同搬运中的阻抗控制

    文章目录 阻抗模型物体阻抗分布阻抗Matlab和RTB仿真物体阻抗分布阻抗 源代码 阻抗模型 阻抗控制的目的是将原有物体动力学修正为我们期望动力学 假设有一个弹簧 xff0c 通过阻抗控制 xff0c 可以使得它的刚度降低 xff0c 实际
  • MATLAB App Designer生成独立GUI(可执行exe)并添加依赖项

    文章目录 写在前面生成步骤设置编译器编写GUI生成exe 常踩的坑 写在前面 近期 xff0c 由于朋友需求以及科研任务要求 xff0c 我研究了一下MATLAB GUI设计 xff0c 写了两个小程序 一个是读取excel部门名单生成ex
  • 用MATLAB仿真仿射队形变换(affine formation maneuver)

    文章目录 写在前面如何仿真静态编队控制构建stress matrixMATLAB求解LMI问题静态编队控制源代码 如何仿真时变轨迹和队形变换轨迹生成时变leader控制律时变轨迹和队形变换源代码 写在前面 原论文标题 xff1a Affin