多移动机器人编队控制与避障系统

多移动机器人编队控制与避障系统

MATLAB实现,用于多移动机器人的编队控制与避障。该系统实现了领航-跟随编队控制算法,并集成了人工势场法进行实时避障。

classdef MultiRobotFormationControl
    % 多机器人编队控制与避障系统
    % 实现领航-跟随编队控制与人工势场避障
    
    properties
        numRobots;          % 机器人数量
        formationType;      % 编队类型 ('V', 'Line', 'Square')
        robotPositions;     % 机器人位置 [x1,y1; x2,y2; ...]
        robotVelocities;    % 机器人速度 [vx1,vy1; vx2,vy2; ...]
        robotGoals;         % 机器人目标位置
        leaderIndex;        % 领航者索引
        obstacles;          % 障碍物位置 [x,y,radius]
        formationOffsets;   % 编队偏移量
        maxSpeed;           % 最大速度
        kAtt;               % 引力系数
        kRep;               % 斥力系数
        d0;                 % 障碍物影响距离
        dt;                 % 时间步长
        safetyDist;         % 安全避障距离
    end
    
    methods
        function obj = MultiRobotFormationControl(numRobots, formationType, startPos, goalPos, obstacles)
            % 构造函数
            obj.numRobots = numRobots;
            obj.formationType = formationType;
            obj.robotPositions = startPos;
            obj.robotVelocities = zeros(numRobots, 2);
            obj.robotGoals = goalPos;
            obj.obstacles = obstacles;
            obj.leaderIndex = 1;  % 第一个机器人为领航者
            obj.maxSpeed = 0.5;   % 最大速度 m/s
            obj.kAtt = 1.0;       % 引力系数
            obj.kRep = 100.0;     % 斥力系数
            obj.d0 = 2.0;         % 障碍物影响距离
            obj.dt = 0.1;         % 时间步长
            obj.safetyDist = 0.5; % 安全避障距离
            
            % 设置编队偏移
            obj = obj.setFormationOffsets();
        end
        
        function obj = setFormationOffsets(obj)
            % 设置编队偏移量
            switch obj.formationType
                case 'V'
                    % V字形编队
                    obj.formationOffsets = [
                        0, 0;       % 领航者
                        -1, 1;      % 右侧跟随者
                        -1, -1;     % 左侧跟随者
                        -2, 2;      % 右侧跟随者2
                        -2, -2;     % 左侧跟随者2
                    ];
                    if obj.numRobots > 5
                        obj.formationOffsets(end+1:end+(obj.numRobots-5), :) = ...
                            (-3:-1:-obj.numRobots+2)'*[1, 1];
                    end
                    
                case 'Line'
                    % 直线编队
                    obj.formationOffsets = [
                        0, 0;       % 领航者
                        -1, 0;      % 跟随者1
                        -2, 0;      % 跟随者2
                        -3, 0;      % 跟随者3
                        -4, 0;      % 跟随者4
                    ];
                    if obj.numRobots > 5
                        obj.formationOffsets(end+1:end+(obj.numRobots-5), :) = ...
                            (-5:-1:-obj.numRobots+1)'*[1, 0];
                    end
                    
                case 'Square'
                    % 方形编队
                    obj.formationOffsets = [
                        0, 0;       % 领航者
                        1, 1;       % 右上
                        1, -1;      % 右下
                        -1, 1;      % 左上
                        -1, -1;     % 左下
                    ];
                    if obj.numRobots > 5
                        obj.formationOffsets(end+1:end+(obj.numRobots-5), :) = ...
                            (-2:-1:-obj.numRobots+3)'*[1, 0];
                    end
                    
                otherwise
                    error('未知的编队类型');
            end
            
            % 截断或扩展偏移量以匹配机器人数量
            if size(obj.formationOffsets, 1) > obj.numRobots
                obj.formationOffsets = obj.formationOffsets(1:obj.numRobots, :);
            elseif size(obj.formationOffsets, 1) < obj.numRobots
                extra = obj.numRobots - size(obj.formationOffsets, 1);
                obj.formationOffsets(end+1:end+extra, :) = rand(extra, 2)*2 - 1;
            end
        end
        
        function [newPositions, newVelocities] = update(obj)
            % 更新机器人位置和速度
            newPositions = obj.robotPositions;
            newVelocities = zeros(obj.numRobots, 2);
            
            % 更新领航者
            leaderGoal = obj.robotGoals(obj.leaderIndex, :);
            [vLeader, ~] = obj.computeVelocity(obj.leaderIndex, leaderGoal);
            newVelocities(obj.leaderIndex, :) = vLeader;
            newPositions(obj.leaderIndex, :) = obj.robotPositions(obj.leaderIndex, :) + vLeader * obj.dt;
            
            % 更新跟随者
            for i = 1:obj.numRobots
                if i == obj.leaderIndex
                    continue;
                end
                
                % 计算期望位置(领航者位置 + 编队偏移)
                desiredPos = newPositions(obj.leaderIndex, :) + obj.formationOffsets(i, :);
                
                % 计算跟随者速度
                [vFollower, ~] = obj.computeVelocity(i, desiredPos);
                newVelocities(i, :) = vFollower;
                newPositions(i, :) = obj.robotPositions(i, :) + vFollower * obj.dt;
            end
            
            % 更新状态
            obj.robotPositions = newPositions;
            obj.robotVelocities = newVelocities;
        end
        
        function [velocity, force] = computeVelocity(obj, robotIdx, targetPos)
            % 计算机器人速度(结合编队控制和避障)
            currentPos = obj.robotPositions(robotIdx, :);
            
            % 1. 计算编队控制力(指向目标位置)
            fAtt = obj.kAtt * (targetPos - currentPos);
            
            % 2. 计算避障力(来自障碍物和其它机器人)
            fRep = [0, 0];
            
            % 障碍物斥力
            for o = 1:size(obj.obstacles, 1)
                obsPos = obj.obstacles(o, 1:2);
                obsRad = obj.obstacles(o, 3);
                
                dist = norm(currentPos - obsPos);
                if dist < obj.d0
                    repDir = (currentPos - obsPos) / dist;
                    repMag = obj.kRep * (1/dist - 1/obj.d0) / (dist^2) * (obsRad + obj.safetyDist);
                    fRep = fRep + repMag * repDir;
                end
            end
            
            % 其他机器人斥力
            for r = 1:obj.numRobots
                if r == robotIdx
                    continue;
                end
                
                otherPos = obj.robotPositions(r, :);
                dist = norm(currentPos - otherPos);
                
                if dist < obj.safetyDist
                    repDir = (currentPos - otherPos) / dist;
                    repMag = obj.kRep * (1/dist - 1/obj.safetyDist) / (dist^2);
                    fRep = fRep + repMag * repDir;
                end
            end
            
            % 3. 合力
            totalForce = fAtt + fRep;
            force = totalForce;
            
            % 4. 计算速度(限制最大速度)
            speed = norm(totalForce);
            if speed > obj.maxSpeed
                velocity = (totalForce / speed) * obj.maxSpeed;
            else
                velocity = totalForce;
            end
        end
        
        function visualize(obj, step)
            % 可视化当前状态
            figure(1);
            clf;
            hold on;
            axis equal;
            grid on;
            title(sprintf('多机器人编队控制 - 步骤 %d', step));
            xlabel('X (m)');
            ylabel('Y (m)');
            
            % 绘制障碍物
            for o = 1:size(obj.obstacles, 1)
                viscircles(obj.obstacles(o, 1:2), obj.obstacles(o, 3), 'Color', 'r');
            end
            
            % 绘制机器人
            colors = lines(obj.numRobots);
            for i = 1:obj.numRobots
                pos = obj.robotPositions(i, :);
                vel = obj.robotVelocities(i, :);
                
                % 绘制机器人位置
                plot(pos(1), pos(2), 'o', 'MarkerSize', 10, ...
                    'MarkerFaceColor', colors(i, :), 'MarkerEdgeColor', 'k');
                
                % 绘制速度方向
                quiver(pos(1), pos(2), vel(1), vel(2), 0.5, 'Color', colors(i, :), 'MaxHeadSize', 2);
                
                % 标注机器人编号
                text(pos(1)+0.1, pos(2)+0.1, num2str(i), 'FontSize', 12);
            end
            
            % 绘制目标位置
            plot(obj.robotGoals(:,1), obj.robotGoals(:,2), 'g*', 'MarkerSize', 15);
            
            % 绘制编队连线
            leaderPos = obj.robotPositions(obj.leaderIndex, :);
            for i = 1:obj.numRobots
                if i ~= obj.leaderIndex
                    followerPos = obj.robotPositions(i, :);
                    plot([leaderPos(1), followerPos(1)], [leaderPos(2), followerPos(2)], 'k--');
                end
            end
            
            % 设置坐标轴范围
            allX = [obj.robotPositions(:,1); obj.robotGoals(:,1); obj.obstacles(:,1)];
            allY = [obj.robotPositions(:,2); obj.robotGoals(:,2); obj.obstacles(:,2)];
            padding = 2;
            xlim([min(allX)-padding, max(allX)+padding]);
            ylim([min(allY)-padding, max(allY)+padding]);
            
            drawnow;
        end
        
        function runSimulation(obj, maxSteps)
            % 运行仿真
            for step = 1:maxSteps
                % 更新机器人状态
                [obj.robotPositions, obj.robotVelocities] = obj.update();
                
                % 可视化
                obj.visualize(step);
                
                % 检查终止条件
                if obj.checkTermination()
                    disp('任务完成!');
                    break;
                end
                
                pause(0.05); % 控制仿真速度
            end
        end
        
        function completed = checkTermination(obj)
            % 检查任务是否完成
            completed = true;
            for i = 1:obj.numRobots
                distToGoal = norm(obj.robotPositions(i, :) - obj.robotGoals(i, :));
                if distToGoal > 0.3 % 距离阈值
                    completed = false;
                    break;
                end
            end
        end
    end
end

仿真脚本

% 多机器人编队控制仿真
clear; close all; clc;

% 仿真参数
numRobots = 4;          % 机器人数量
formationType = 'V';    % 编队类型: 'V', 'Line', 'Square'
simTime = 60;           % 仿真时间 (秒)
dt = 0.1;               % 时间步长 (秒)
maxSteps = simTime/dt;  % 最大步数

% 创建机器人初始位置 (随机分布)
startArea = [0, 0; 10, 10]; % 起始区域
startPos = startArea(1,:) + rand(numRobots, 2) .* (startArea(2,:) - startArea(1,:));

% 创建目标位置 (集中在一个区域)
goalArea = [20, 0; 30, 10]; % 目标区域
goalPos = goalArea(1,:) + rand(numRobots, 2) .* (goalArea(2,:) - goalArea(1,:));

% 创建障碍物
obstacles = [
    15, 5, 1.5;   % [x, y, radius]
    18, 2, 1.0;
    22, 7, 1.2;
    25, 3, 0.8;
    20, 8, 1.0
];

% 创建编队控制系统
formationSystem = MultiRobotFormationControl(...
    numRobots, formationType, startPos, goalPos, obstacles);

% 运行仿真
formationSystem.runSimulation(maxSteps);

系统功能说明

1. 编队控制算法

2. 避障算法

3. 可视化功能

4. 参数配置

扩展功能建议

1. 增加通信拓扑控制

function obj = setCommunicationTopology(obj, topologyType)
    % 设置通信拓扑
    switch topologyType
        case 'FullConnected'
            % 全连接拓扑
            obj.adjacencyMatrix = ones(obj.numRobots) - eye(obj.numRobots);
        case 'Ring'
            % 环形拓扑
            adjMat = zeros(obj.numRobots);
            for i = 1:obj.numRobots
                adjMat(i, mod(i, obj.numRobots)+1) = 1;
                adjMat(mod(i, obj.numRobots)+1, i) = 1;
            end
            obj.adjacencyMatrix = adjMat;
        case 'Star'
            % 星形拓扑(领航者为中心)
            adjMat = zeros(obj.numRobots);
            adjMat(obj.leaderIndex, :) = 1;
            adjMat(:, obj.leaderIndex) = 1;
            adjMat(obj.leaderIndex, obj.leaderIndex) = 0;
            obj.adjacencyMatrix = adjMat;
        otherwise
            error('未知拓扑类型');
    end
end

2. 添加路径规划算法

function path = planPath(start, goal, obstacles)
    % 使用A*算法规划路径
    % 实现略...
end

3. 实现分布式控制

function [newPositions, newVelocities] = distributedUpdate(obj)
    % 分布式更新规则
    newPositions = obj.robotPositions;
    newVelocities = zeros(obj.numRobots, 2);
    
    for i = 1:obj.numRobots
        % 获取邻居信息
        neighbors = find(obj.adjacencyMatrix(i, :));
        
        % 计算共识项
        consensusTerm = [0, 0];
        for j = neighbors
            consensusTerm = consensusTerm + (obj.robotPositions(j, :) - obj.robotPositions(i, :));
        end
        
        % 计算控制输入
        if i == obj.leaderIndex
            % 领航者行为
            goalDir = obj.robotGoals(i, :) - obj.robotPositions(i, :);
            controlInput = 0.5*goalDir + 0.1*consensusTerm;
        else
            % 跟随者行为
            controlInput = 0.3*consensusTerm;
        end
        
        % 添加避障
        [avoidanceForce, ~] = obj.computeAvoidanceForce(i);
        controlInput = controlInput + avoidanceForce;
        
        % 更新速度和位置
        speed = norm(controlInput);
        if speed > obj.maxSpeed
            newVelocities(i, :) = (controlInput / speed) * obj.maxSpeed;
        else
            newVelocities(i, :) = controlInput;
        end
        
        newPositions(i, :) = obj.robotPositions(i, :) + newVelocities(i, :) * obj.dt;
    end
end

4. 添加故障检测与恢复

function obj = detectAndHandleFailures(obj)
    % 检测机器人故障
    for i = 1:obj.numRobots
        % 检查机器人是否卡住
        if norm(obj.robotVelocities(i, :)) < 0.01
            stuckCounter(i) = stuckCounter(i) + 1;
        else
            stuckCounter(i) = 0;
        end
        
        % 如果机器人卡住超过阈值,重新分配角色
        if stuckCounter(i) > 20
            fprintf('机器人 %d 可能卡住,重新分配角色\n', i);
            obj.handleStuckRobot(i);
        end
    end
end

使用说明

  1. 初始化系统

    formationSystem = MultiRobotFormationControl(numRobots, formationType, startPos, goalPos, obstacles);
    
  2. 运行仿真

    formationSystem.runSimulation(maxSteps);
    
  3. 自定义参数

    • 修改formationType选择编队类型
    • 调整kAttkRep改变控制行为
    • obstacles数组中定义障碍物
  4. 结果分析

    • 系统会自动显示实时动画
    • 可通过修改visualize方法添加数据记录
    • 使用checkTermination判断任务完成情况

参考代码 实现多个移动机器人的编队控制及其避障 www.youwenfan.com/contentcss/101171.html

实际应用建议

  1. 硬件集成

    • 将算法部署到ROS系统
    • 使用实际机器人平台(如TurtleBot、Jackal)
    • 添加传感器融合模块(激光雷达、IMU)
  2. 性能优化

    • 对于大规模群体,使用近似计算方法
    • 实现分层控制架构
    • 添加事件触发机制减少通信开销
  3. 复杂环境适应

    • 集成SLAM技术进行实时定位
    • 添加动态障碍物预测
    • 实现多目标点分配策略
  4. 人机协作

    • 添加人类操作者接口
    • 实现人在回路的控制模式
    • 开发异常行为检测系统

 

专注于matlab/simulink,电子电路,编程