文章目录
- 前言
- 一、Function 'quiver' not supported for code generation.
- 二、在仿真环境中添加障碍物
- 三、simulink中function函数初始化
- 五、在MATLAB中,实现在绘图时只删除上一次绘制的图形而不是整个图形界面
- 六、matlab simulink中,程序不断发出机器人位置信息,创建一个模块收集机器人从开始到结束的所有位姿
- 总结
前言
近期实验室购置了阿木实验室KKSwarm集群仿真平台,其整体开放环境为MATLAB,近期基于该平台做了一些集群编队的工作,期间遇到了一些小问题,记录下遇到的问题和解决方法。

一、Function ‘quiver’ not supported for code generation.
解决方法:添加coder.extrinsic('quiver'),其他的同理~
二、在仿真环境中添加障碍物
解决方法:添加coder.extrinsic('quiver'),其他的同理~
三、simulink中function函数初始化
matlab中搭建的simulink,每次有参数传入后都会初始化函数的定义,但只想在参数第一次传入时进行初始化,后面调用时不再初始化。
 persistent k
    persistent pose_x
    persistent pose_y
    persistent pose_th
    persistent h_circle
    persistent h_quiver
    persistent h1_arrows
    persistent h2_arrows
    
    if isempty(k)
        k = 0;
    end
    if isempty(pose_x)
        pose_x = zeros(6,5000);  % 初始化x坐标的空矩阵
    end
    if isempty(pose_y)
        pose_y = zeros(6,5000);  % 初始化y坐标的空矩阵
    end
    if isempty(pose_th)
        pose_th = zeros(6,5000);  % 初始化th坐标的空矩阵
    end
    if isempty(h_circle)
        h_circle = zeros(6,1);  % 初始化th坐标的空矩阵
    end
    if isempty(h_quiver)
        h_quiver = zeros(6,1);  % 初始化th坐标的空矩阵
    end
    if isempty(h1_arrows)
        h1_arrows = zeros(6,6);  % 初始化th坐标的空矩阵
    end
    if isempty(h2_arrows)
        h2_arrows = zeros(6,6);  % 初始化th坐标的空矩阵
    end
五、在MATLAB中,实现在绘图时只删除上一次绘制的图形而不是整个图形界面
目前已知各个机器人的位置,仿真时把个机器人之间通过线段连接起来,并且每当有新的位置信息传入时,只删除之前的连线。但保留机器人的轨迹。
 %% ====Animation====
            area = compute_area(pose_x(1,k),pose_y(1,k),0.5);
            %hold off;
            ArrowLength=0.1; 
            for j=1:N
                 h_quiver(j) = quiver(pose_x(j,k),pose_y(j,k),ArrowLength*cos(pose_th(j,k)),ArrowLength*sin(pose_th(j,k)),'*k');hold on;
                if j==1
                    state=2;
                else
                    state=1;
                end
                    h_circle(j) = draw_circle (pose_x(j,k),pose_y(j,k),0.06,state);hold on;
            end
    
            for i=1:N
                for j=1:N
                    if A(i,j)==1
                         [lineHandle, arrowHandle] = draw_arrow([pose_x(j,k),pose_y(j,k)],[pose_x(i,k),pose_y(i,k)], 0.05);hold on;
                         h1_arrows(i, j) = lineHandle;
                         h2_arrows(i, j) = arrowHandle;
                    end
                end
            end
    
            if size(ob_temp)~=[0 0]
                plot(ob_temp(:,1),ob_temp(:,2),'Xk','LineWidth',2);hold on;
            end
            axis(area);
            grid on;
            drawnow; 
            for j=1:N
            delete(h_quiver(j));
            end
            for j=1:N
            delete(h_circle(j));
            end
            for i=1:N
                for j=1:N
                    if A(i,j)==1
                      delete(h1_arrows(i, j)); % 删除线条
                      delete(h2_arrows(i, j)); % 删除箭头头部
                    end
                end
            end
 color='mgbkrc';
    for i=1:N
        plot(pose_x(i,5:k),pose_y(i,5:k),color(1,i),'LineWidth',2);
        hold on
    end
需要注意的是,想要单独删除某个绘制的图形时,需要创建句柄表示绘制出的图形,通过delete进行删除。但如果调用.m文件进行画图时,确保调用的.m文件有对应的返回值,否则句柄无法收到消息,进而无法通过delete删除。
 举例:
//单独删除箭头draw_arrow图形,包含两部分箭头和线段,要添加两个返回值a,b
function [a,b] = draw_arrow(startpoint,endpoint,headsize) 
% draw the communication direction between two agents
% accepts two [x y] coords and one double headsize 
v1 = headsize*(startpoint-endpoint)/sqrt((startpoint(1)-endpoint(1))^2+(startpoint(2)-endpoint(2))^2);
theta = 22.5*pi/180; 
theta1 = -1*22.5*pi/180; 
rotMatrix = [cos(theta)  -sin(theta) ; sin(theta)  cos(theta)];
rotMatrix1 = [cos(theta1)  -sin(theta1) ; sin(theta1)  cos(theta1)];  
v2 = v1*rotMatrix; 
v3 = v1*rotMatrix1;
x1 = endpoint+2*v1;
x2 = x1 + v2;
x3 = x1 + v3;
b = fill([x1(1) x2(1) x3(1)],[x1(2) x2(2) x3(2)],[0 0 0]);% this fills the arrowhead (black) 
a = plot([startpoint(1) endpoint(1)],[startpoint(2) endpoint(2)],'linewidth',0.5,'color',[0 0 0]);
//同样在调用时储存每次画出的图形
            for i=1:N
                for j=1:N
                    if A(i,j)==1
                         [lineHandle, arrowHandle] = draw_arrow([pose_x(j,k),pose_y(j,k)],[pose_x(i,k),pose_y(i,k)], 0.05);hold on;
                         h1_arrows(i, j) = lineHandle;
                         h2_arrows(i, j) = arrowHandle;
                    end
                end
            end
//对应的删除操作
            for i=1:N
                for j=1:N
                    if A(i,j)==1
                      delete(h1_arrows(i, j)); % 删除线条
                      delete(h2_arrows(i, j)); % 删除箭头头部
                    end
                end
            end
六、matlab simulink中,程序不断发出机器人位置信息,创建一个模块收集机器人从开始到结束的所有位姿
wp1传入[10x3]列的矩阵,前6行依次代表6个机器人的位置坐标,后4行代表障碍物的位置坐标,每当有新的位置传进来wp1就会更新,记录下各机器人从开始位置到目标位置的所有坐标。
 开始时采用的办法:
function saveData(pose_x, pose_y, pose_th)
    % 保存数据到 .mat 文件
    save('robot_pose_data.mat', 'pose_x', 'pose_y', 'pose_th');
end
但运行时save一直报错,无法保存机器人位置数据。
 最终采用的方法:
 
 通过To Workspace分别来收集机器人当前时刻位姿和当前时刻的目标位姿:
 代码:
function [xp1,xp2,xp3,xp11,xp22,xp33] = visualizeRobots(wp1)
    N = 6;
     persistent poseX
     persistent poseY
     persistent poseth
     persistent poseXX
     persistent poseYY
     persistent posethth
    %% Adjacent matrix
    A=[0 0 0 0 0 0;     % a(ij)
       1 0 1 1 0 0;
       1 1 0 0 0 1;
       1 1 0 0 1 0;
       1 0 0 1 0 1;
       1 0 1 0 1 0];
%     delta_x = [0 -0.2  0.2 -0.4  0.0  0.4];   % 6个机器人相对间隔误差每一列代表一个机器人
%     delta_y = [0  0.4  0.4  0.0 -0.3  0.0];   % 领航者与自己无误差
   
       
        % 计算当前机器人的目标位置
        pos_targetsX =  [wp1(1,1)  wp1(1,1)-0.2  wp1(1,1)+0.2  wp1(1,1)-0.4  wp1(1,1)      wp1(1,1)+0.4];
        pos_targetsY =  [wp1(1,2)  wp1(1,2)+0.4  wp1(1,2)+0.4  wp1(1,2)      wp1(1,2)-0.3  wp1(1,2)];
        pos_targetsth =  [wp1(1,3)  wp1(1,3)      wp1(1,3)      wp1(1,3)      wp1(1,3)      wp1(1,3)];
          
%     if isempty(posel)
%         posel = zeros(6,1);  % 初始化x坐标的空矩阵
%     end
coder.extrinsic('quiver','draw_circle','draw_arrow','gcs','get_param','assign') ; 
    % 存放机器人的位姿
    pose_x = wp1(1:6, 1);
    pose_y = wp1(1:6, 2); 
    pose_th = wp1(1:6, 3);
    % 存放障碍物的位置
    ob_temp = [wp1(7:10,1),wp1(7:10,2)];
    % 将当前数据存入历史数据
    %historyData{end+1} = struct('pose_x', pose_x, 'pose_y', pose_y, 'pose_th', pose_th, 'obstacles', ob_temp);
    %% ====Animation====
            area = compute_area(pose_x(1),pose_y(1),0.5);
            hold off;
            ArrowLength=0.1; 
            for j=1:N
                quiver(pose_x(j),pose_y(j),ArrowLength*cos(pose_th(j)),ArrowLength*sin(pose_th(j)),'*k');hold on;
                if j==1
                    state=2;
                else
                    state=1;
                end
                draw_circle (pose_x(j),pose_y(j),0.06,state);hold on;
            end
    
            for i=1:N
                for j=1:N
                    if A(i,j)==1
                        draw_arrow([pose_x(j),pose_y(j)],[pose_x(i),pose_y(i)], 0.05);hold on;
                    end
                end
            end
    
            if size(ob_temp)~=[0 0]
                plot(ob_temp(:,1),ob_temp(:,2),'Xk','LineWidth',2);hold on;
            end
            axis(area);
            grid on;
            drawnow;    
            poseX = pose_x;
            poseY = pose_y;
            poseth = pose_th;
            poseXX = pos_targetsX;
            poseYY = pos_targetsY;
            posethth = pos_targetsth;
            xp1 = poseX';
            xp2 = poseY';
            xp3 = poseth';
            xp11 = poseXX;
            xp22 = poseYY;
            xp33 = posethth;
            
end
保存的数据:
 
总结
最终借助MATLAB强大的数据分析功能绘制出,预期的图形:
 
 

因为才开始学习使用Matlab还用许多不清楚的地方,故记录下遇到的问题供以后温故知新!



















