轨迹跟踪比例P的实现move2pose

通过对当前航点到目标点的距离比例关系转换成速度。v = kp*s ,距离s越大 v越大,反之越小。随着距离的拉近速度变小为0.导致速度不够平滑。

会有快慢快慢的问题出现。连续点的时候需要进行优化。

目标角度对当前的航向角求比例转换成 角速度。

α = tan(dy,dx)- start_theta;
β = theta_goal - theta - (tan(dy,dx)-theta);
  = theta_goal - tan(dy,dx);
  
dθ = α + β = theta_goal - start_theta ;
上式中 dθ就是为要旋转的角度。dθ > 0 向右转。
dθ <0 向左转。
实际中需要加入 影响比例,该参数需要调试。
dθ = kα + pβ;k的值决定了向右转的幅度,p决定了向左转的幅度。
k越大转向角度越大,p同理.太小的话会导致转弯半径太大无法以最短的距离
行驶 到下一个航点。
 微信截图_20210508180011.png

python 源码


"""
Move to specified pose
Author: Daniel Ingram (daniel-s-ingram)
        Atsushi Sakai(@Atsushi_twi)
P. I. Corke, "Robotics, Vision & Control", Springer 2017, ISBN 978-3-319-54413-7
"""

import matplotlib.pyplot as plt
import numpy as np
from random import random

# simulation parameters
Kp_rho = 9
Kp_alpha = 35.0#15
Kp_beta = -0.0#-3
dt = 0.01

show_animation = True


def move_to_pose(x_start, y_start, theta_start, x_goal, y_goal, theta_goal):
    """
    rho is the distance between the robot and the goal position
    alpha is the angle to the goal relative to the heading of the robot
    beta is the angle between the robot's position and the goal position plus the goal angle
    Kp_rho*rho and Kp_alpha*alpha drive the robot along a line towards the goal
    Kp_beta*beta rotates the line so that it is parallel to the goal angle
    """
    x = x_start
    y = y_start
    theta = theta_start

    x_diff = x_goal - x
    y_diff = y_goal - y

    x_traj, y_traj = [], []

    rho = np.hypot(x_diff, y_diff)
    dis = rho
    while rho > 0.001:
        x_traj.append(x)
        y_traj.append(y)

        x_diff = x_goal - x
        y_diff = y_goal - y

        # Restrict alpha and beta (angle differences) to the range
        # [-pi, pi] to prevent unstable behavior e.g. difference going
        # from 0 rad to 2*pi rad with slight turn

        rho = np.hypot(x_diff, y_diff)
        alpha = (np.arctan2(y_diff, x_diff)
                 - theta + 0 ) #% (2 * np.pi) - np.pi
        if  (alpha < -np.pi):                    
            alpha = alpha + 2 * np.pi 
        elif(alpha > np.pi):
            alpha = alpha - 2 * np.pi 
        #beta = (theta_goal - theta - alpha + np.pi) % (2 * np.pi) - np.pi
        beta = theta_goal - theta - alpha
        if  (beta < -np.pi):                     
            beta = beta + 2 * np.pi 
        elif(beta > np.pi):
            beta = beta - 2 * np.pi        
        if rho > dis/2:
            v = Kp_rho * rho
        else :
            v = 0.5
        v = Kp_rho * rho
        w = Kp_alpha * alpha + Kp_beta * beta
        
        #if alpha > np.pi / 2 or alpha < -np.pi / 2:
            #v = -v
        print(rho,alpha*180/3.14,beta*180/3.14,v,w,x,y,theta*180/3.14)
        theta = theta + w * dt
        x = x + v * np.cos(theta) * dt
        y = y + v * np.sin(theta) * dt
        
        if show_animation:  # pragma: no cover
            plt.cla()
            plt.arrow(x_start, y_start, np.cos(theta_start),
                      np.sin(theta_start), color='r', width=0.1)
            plt.arrow(x_goal, y_goal, np.cos(theta_goal),
                      np.sin(theta_goal), color='g', width=0.1)
            plot_vehicle(x, y, theta, x_traj, y_traj)


def plot_vehicle(x, y, theta, x_traj, y_traj):  # pragma: no cover
    # Corners of triangular vehicle when pointing to the right (0 radians)
    p1_i = np.array([0.5, 0, 1]).T
    p2_i = np.array([-0.5, 0.25, 1]).T
    p3_i = np.array([-0.5, -0.25, 1]).T

    T = transformation_matrix(x, y, theta)
    p1 = np.matmul(T, p1_i)
    p2 = np.matmul(T, p2_i)
    p3 = np.matmul(T, p3_i)

    plt.plot([p1[0], p2[0]], [p1[1], p2[1]], 'k-')
    plt.plot([p2[0], p3[0]], [p2[1], p3[1]], 'k-')
    plt.plot([p3[0], p1[0]], [p3[1], p1[1]], 'k-')

    plt.plot(x_traj, y_traj, 'b--')

    # for stopping simulation with the esc key.
    plt.gcf().canvas.mpl_connect('key_release_event',
            lambda event: [exit(0) if event.key == 'escape' else None])

    plt.xlim(0, 20)
    plt.ylim(0, 20)

    plt.pause(dt)


def transformation_matrix(x, y, theta):
    return np.array([
        [np.cos(theta), -np.sin(theta), x],
        [np.sin(theta), np.cos(theta), y],
        [0, 0, 1]
    ])


def main():
    x_goal = 2
    for i in range(1):
        x_start = 1 
        y_start = 10 
        theta_start = 130*3.1415/180
        x_goal  =5 
        y_goal = 12 
        theta_goal = 50*3.1415/180
        print("Initial x: %.2f m\nInitial y: %.2f m\nInitial theta: %.2f rad\n" %
              (x_start, y_start, theta_start))
        print("Goal x: %.2f m\nGoal y: %.2f m\nGoal theta: %.2f rad\n" %
              (x_goal, y_goal, theta_goal))
        move_to_pose(x_start, y_start, theta_start, x_goal, y_goal, theta_goal)


if __name__ == '__main__':
    main()
可以尝试修改KP ALPHA ,KP-BETA 进行测试。



sitemap