Main Content

이동 로봇을 위한 다양한 기구학 모델 시뮬레이션하기

이 예제에서는 하나의 환경에서 다양한 로봇 기구학 모델을 모델링하고 비교하는 방법을 보여줍니다.

기구학 제약 조건을 가진 이동 로봇 정의하기

이동 로봇의 기구학을 모델링하는 방법은 여러 가지가 있습니다. 모든 모델링 방법은 바퀴 속도가 로봇 상태 [x y theta], 즉 xy 좌표와 라디안 단위의 로봇 방향 theta와 어떻게 연결되는지를 규정합니다.

외륜 기구학 모델

이동 로봇 이동체 기구학을 나타내는 가장 간단한 방법은 외륜 모델입니다. 이 모델은 중심 차축을 중심으로 하는 회전으로 바퀴 속도가 설정되고 z축을 중심으로 회전할 수 있습니다. 입력값이 이동체 속도와 방향 변화율로 제공되고 그 외 제약 조건이 고려되지 않을 경우 차동 구동 모델과 자전거 기구학 모델은 모두 외륜 기구학으로 축소됩니다.

unicycle = unicycleKinematics(VehicleInputs="VehicleSpeedHeadingRate");

차동 구동 기구학 모델

차동 구동 모델은 후방 구동 차축을 사용하여 이동체 속도와 방향 변화율을 모두 제어합니다. 구동 차축의 바퀴는 양방향으로 회전할 수 있습니다. 대부분의 이동 로봇은 로우 레벨의 바퀴 명령 인터페이스만 일부 가지므로 이 모델은 마찬가지로 이동체 속도와 방향 변화율을 입력값으로 사용하여 이동체 제어를 단순화합니다.

diffDrive = differentialDriveKinematics(VehicleInputs="VehicleSpeedHeadingRate");

외륜 모델과 동작을 구별하기 위해 차동 구동 기구학 모델에 바퀴 속도 제약 조건을 추가합니다.

diffDrive.WheelSpeedRange = [-10 10]*2*pi;

자전거 기구학 모델

자전거 모델은 로봇을 2개의 차축, 즉 후방 구동 차축과 z축을 중심으로 회전하는 전방 차축을 가진 차륜 모델로 처리합니다. 자전거 모델은 각 차축의 바퀴가 하나의 중심 바퀴로 모델링될 수 있고, 자전거처럼 전방 바퀴의 방향을 직접 설정할 수 있다는 가정하에 작동합니다.

bicycle = bicycleKinematics(VehicleInputs="VehicleSpeedHeadingRate",MaxSteeringAngle=pi/8);

기타 모델

Ackermann 기구학 모델은 변형된 차륜 모델로, Ackermann 조향을 가정합니다. 대부분의 차륜 이동체에서 앞바퀴는 같은 축을 중심으로 회전하는 것이 아니라, 이동체 회전의 가운데를 중심으로 동심원을 그리며 주행할 수 있도록 약간 다른 축에서 회전합니다. 이 회전 각도의 차이를 Ackermann 조향이라고 부르며, 일반적으로 실제 차량에서는 메커니즘에 따라 적용됩니다. 이동체 및 바퀴 기구학 관점에서는 조향각을 비율 입력으로 처리하여 적용할 수 있습니다. 이 시뮬레이션은 이 기구학 모델을 포함하지 않지만, 모델에 대한 자세한 내용은 ackermannKinematics 항목을 참조하십시오.

carLike = ackermannKinematics;

시뮬레이션 파라미터 설정하기

이러한 이동 로봇은 다양한 기구학으로 인해 발생하는 몇 가지 차이를 보여주도록 설계된 일련의 웨이포인트를 따라갑니다.

waypoints = [0 0; 0 10; 10 10; 5 10; 11 9; 4 -5];
% Define the total time and the sample rate
sampleTime = 0.05;               % Sample time [s]
tVec = 0:sampleTime:20;          % Time array
initPose = [waypoints(1,:)'; 0]; % Initial pose (x y theta)

이동체 제어기 만들기

이동체는 Pure Pursuit 제어기를 사용하여 일련의 웨이포인트를 따라갑니다. 일련의 웨이포인트, 로봇의 현재 상태, 몇 가지 다른 파라미터가 주어지면 제어기는 이동체 속도와 방향 변화율을 출력합니다.

% Define a controller. Each robot requires its own controller
controller1 = controllerPurePursuit(Waypoints=waypoints,DesiredLinearVelocity=3,MaxAngularVelocity=3*pi);
controller2 = controllerPurePursuit(Waypoints=waypoints,DesiredLinearVelocity=3,MaxAngularVelocity=3*pi);
controller3 = controllerPurePursuit(Waypoints=waypoints,DesiredLinearVelocity=3,MaxAngularVelocity=3*pi);

ODE 솔버를 사용하여 모델 시뮬레이션하기

모델은 derivative 함수를 사용하여 상태를 업데이트하면서 시뮬레이션됩니다. 이 예제에서는 ODE(상미분 방정식) 솔버를 사용하여 해를 생성합니다. 또 다른 방법은 차동 구동 로봇의 경로 추종에 나와 있듯이 루프를 사용하여 상태를 업데이트하는 것입니다.

ODE 솔버에서는 모든 출력값이 단일 출력값으로 제공되어야 하므로, Pure Pursuit 제어기는 선형 속도와 방향 각속도를 단일 출력값으로 출력하는 함수에 래핑되어야 합니다. 예제 헬퍼 exampleHelperMobileRobotController가 이 목적으로 사용됩니다. 또한 이 예제 헬퍼는 로봇이 목표의 지정된 반경 내에 있을 때 정지하도록 합니다.

goalPoints = waypoints(end,:)';
goalRadius = 1;

ode45는 각 모델 유형에 대해 한 번씩 호출됩니다. 도함수는 initPose에 의해 설정된 초기 상태로 상태 출력값을 계산합니다. 각 도함수는 대응하는 기구학 모델 객체, 현재 로봇 자세, 해당 자세에서의 제어기 출력값을 받습니다.

% Compute trajectories for each kinematic model under motion control
[tUnicycle,unicyclePose] = ode45(@(t,y)derivative(unicycle,y,exampleHelperMobileRobotController(controller1,y,goalPoints,goalRadius)),tVec,initPose);
[tBicycle,bicyclePose] = ode45(@(t,y)derivative(bicycle,y,exampleHelperMobileRobotController(controller2,y,goalPoints,goalRadius)),tVec,initPose);
[tDiffDrive,diffDrivePose] = ode45(@(t,y)derivative(diffDrive,y,exampleHelperMobileRobotController(controller3,y,goalPoints,goalRadius)),tVec,initPose);

결과 플로팅하기

ODE 솔버의 결과는 plotTransforms를 사용해 모든 궤적의 결과를 한 번에 시각화하여 단일 플롯에서 쉽게 볼 수 있습니다.

자세 출력값은 먼저 평행 이동과 쿼터니언으로 구성된, 인덱싱된 행렬로 변환되어야 합니다.

unicycleTranslations = [unicyclePose(:,1:2) zeros(length(unicyclePose),1)];
unicycleRot = axang2quat([repmat([0 0 1],length(unicyclePose),1) unicyclePose(:,3)]);

bicycleTranslations = [bicyclePose(:,1:2) zeros(length(bicyclePose),1)];
bicycleRot = axang2quat([repmat([0 0 1],length(bicyclePose),1) bicyclePose(:,3)]);

diffDriveTranslations = [diffDrivePose(:,1:2) zeros(length(diffDrivePose),1)];
diffDriveRot = axang2quat([repmat([0 0 1],length(diffDrivePose),1) diffDrivePose(:,3)]);

다음으로, 모든 변환의 집합을 위에서 내려보도록 플로팅할 수 있습니다. 외륜, 자전거, 차동 구동 로봇의 경로는 각각 빨간색, 파란색, 녹색입니다. 플롯을 단순화하기 위해, 출력값을 10개마다 하나씩 표시합니다.

figure
plot(waypoints(:,1),waypoints(:,2),"kx-",MarkerSize=20);
hold all
plotTransforms(unicycleTranslations(1:10:end,:),unicycleRot(1:10:end,:),MeshFilePath="groundvehicle.stl",MeshColor="r");
plotTransforms(bicycleTranslations(1:10:end,:),bicycleRot(1:10:end,:),MeshFilePath="groundvehicle.stl",MeshColor="b");
plotTransforms(diffDriveTranslations(1:10:end,:),diffDriveRot(1:10:end,:),MeshFilePath="groundvehicle.stl",MeshColor="g");
axis equal
view(0,90)