双差速轮AGV的运动学正解和逆解

简介:

双差速轮AGV(Automated Guided Vehicle)是一种常见的移动机器人结构,采用两侧独立驱动的车轮,通过控制左右轮的转速差实现运动和转向。理解其运动学正解(由轮速求车辆运动)和逆解(由期望运动求轮速)对于AGV的设计和控制至关重要。

运动学模型建立:

定义变量
  • 𝑣:AGV的线速度(质心速度),单位:米/秒(m/s)
  • 𝜔:AGV的角速度(绕质心的旋转速度),单位:弧度/秒(rad/s)
  • 𝑣L、𝑣R :左、右轮的线速度,单位:米/秒(m/s)
  • 𝜔L、𝜔R:左、右轮的角速度,单位:弧度/秒(rad/s)
  • r:车轮半径,单位:米(m)
  • 𝐿:左右车轮之间的轴距(轮间距),单位:米(m)
  • (x,y,θ):AGV在全局坐标系中的位置和朝向
运动学正解(Forward Kinematics):
  • 已知左右轮的角速度,求AGV的线速度、角速度和位姿变化。
步骤:
  • 1、计算左右轮的线速度:
    在这里插入图片描述
  • 2、计算AGV的线速度和角速度:
    在这里插入图片描述
  • 3、更新AGV的位姿(在小时间间隔 Δt 内):
    在这里插入图片描述
示例:
假设:
  • 车轮半径 r=0.1 m
  • 轴距 L=0.5 m
  • 左轮角速度 𝜔L=10 rad/s
  • 右轮角速度 𝜔R=15 rad/s
  • 初始位姿 (x,y,θ)=(0,0,0)
  • 时间间隔 Δt=1s
计算:
  • 1、左右轮线速度:
    在这里插入图片描述
  • 2、AGV的线速度和角速度:
    在这里插入图片描述
  • 3、更新位姿:
    在这里插入图片描述
运动学逆解(Inverse Kinematics):
  • 已知AGV的线速度和角速度,求左右轮的线速度、角速度。
步骤:
1、计算左右轮的线速度:

在这里插入图片描述

2、计算左右轮的角速度:

在这里插入图片描述

示例:
假设:
  • 期望AGV线速度 v=1 m/s
  • 期望AGV角速度 ω=0.5 rad/s
  • 车轮半径 r=0.1 m
  • 轴距 L=0.5 m
计算:
  • 1、左右轮线速度:
    在这里插入图片描述
  • 2、左右轮角速度:
    在这里插入图片描述

注意事项:

  • 速度限制: 确保计算得到的轮速不超过电机和驱动系统的最大能力。
  • 轮滑和打滑: 理论模型假设轮子与地面无滑动,实际应用中应考虑轮滑对控制的影响。
  • 控制周期: 在实际控制中,选择合适的控制周期 Δt 以平衡控制精度和计算负荷。
  • 单位一致性: 确保所有计算中的单位一致,避免因单位不一致导致的计算错误。

实现代码

以下是双差速轮AGV运动学正解和逆解的C++实现代码。代码包括了计算AGV的线速度和角速度(正解),以及根据期望的线速度和角速度计算左右轮的角速度(逆解)。

#include <iostream>
#include <cmath>

const double PI = 3.14159265358979323846;

// AGV参数
struct AGVParameters {
    double wheel_radius;  // 车轮半径(单位:米)
    double axle_length;   // 轮间距(轴距,单位:米)
};

// AGV状态
struct AGVState {
    double x;      // X位置(单位:米)
    double y;      // Y位置(单位:米)
    double theta;  // 朝向角(单位:弧度)
};

// 轮速
struct WheelSpeeds {
    double left;   // 左轮角速度(单位:弧度/秒)
    double right;  // 右轮角速度(单位:弧度/秒)
};

// 线速度和角速度
struct Velocity {
    double linear;      // 线速度(单位:米/秒)
    double angular;     // 角速度(单位:弧度/秒)
};

// 运动学正解:由轮速计算AGV速度
Velocity forwardKinematics(const WheelSpeeds& wheel_speeds, const AGVParameters& params) {
    // 计算左右轮的线速度
    double v_left = params.wheel_radius * wheel_speeds.left;
    double v_right = params.wheel_radius * wheel_speeds.right;

    // 计算AGV的线速度和角速度
    Velocity vel;
    vel.linear = (v_left + v_right) / 2.0;
    vel.angular = (v_right - v_left) / params.axle_length;

    return vel;
}

// 运动学逆解:由AGV速度计算轮速
WheelSpeeds inverseKinematics(const Velocity& vel, const AGVParameters& params) {
    // 计算左右轮的线速度
    double v_left = vel.linear - (params.axle_length / 2.0) * vel.angular;
    double v_right = vel.linear + (params.axle_length / 2.0) * vel.angular;

    // 转换为轮的角速度
    WheelSpeeds wheel_speeds;
    wheel_speeds.left = v_left / params.wheel_radius;
    wheel_speeds.right = v_right / params.wheel_radius;

    return wheel_speeds;
}

// 更新AGV的位姿
void updateAGVState(AGVState& state, const Velocity& vel, double delta_time) {
    state.x += vel.linear * cos(state.theta) * delta_time;
    state.y += vel.linear * sin(state.theta) * delta_time;
    state.theta += vel.angular * delta_time;

    // 确保theta在[-pi, pi]范围内
    if (state.theta > PI) {
        state.theta -= 2 * PI;
    } else if (state.theta < -PI) {
        state.theta += 2 * PI;
    }
}

int main() {
    // 初始化AGV参数
    AGVParameters params;
    params.wheel_radius = 0.1;   // 车轮半径为0.1米
    params.axle_length = 0.5;    // 轴距为0.5米

    // 初始化AGV状态
    AGVState state;
    state.x = 0.0;
    state.y = 0.0;
    state.theta = 0.0;

    // 设置时间步长
    double delta_time = 0.1;  // 时间步长为0.1秒

    // 示例:运动学逆解
    Velocity desired_vel;
    desired_vel.linear = 1.0;     // 期望线速度1.0 m/s
    desired_vel.angular = 0.5;    // 期望角速度0.5 rad/s

    // 计算需要的轮速
    WheelSpeeds wheel_speeds = inverseKinematics(desired_vel, params);

    std::cout << "需要的左轮角速度: " << wheel_speeds.left << " rad/s" << std::endl;
    std::cout << "需要的右轮角速度: " << wheel_speeds.right << " rad/s" << std::endl;

    // 模拟运动一段时间
    for (int i = 0; i < 50; ++i) {
        // 使用轮速计算当前速度(运动学正解)
        Velocity current_vel = forwardKinematics(wheel_speeds, params);

        // 更新AGV状态
        updateAGVState(state, current_vel, delta_time);

        // 输出当前状态
        std::cout << "时间: " << (i + 1) * delta_time << " s, "
                  << "位置: (" << state.x << ", " << state.y << "), "
                  << "朝向: " << state.theta << " rad" << std::endl;
    }

    return 0;
}

代码说明:

  • AGVParameters:定义AGV的物理参数,包括车轮半径和轴距。
  • AGVState:存储AGV的位姿信息,包括位置(x, y)和朝向角(theta)。
  • WheelSpeeds:左右轮的角速度。
  • Velocity:AGV的线速度和角速度。
主要函数:
forwardKinematics:
  • 输入:轮速(WheelSpeeds)和AGV参数(AGVParameters)。
  • 输出:AGV的线速度和角速度(Velocity)。
  • 功能:根据左右轮的角速度计算AGV的线速度和角速度。
inverseKinematics:
  • 输入:期望的AGV线速度和角速度(Velocity)以及AGV参数(AGVParameters)。
  • 输出:需要的左右轮角速度(WheelSpeeds)。
  • 功能:根据期望的AGV运动,计算所需的左右轮角速度。
updateAGVState:
  • 输入:当前AGV状态(AGVState)、AGV速度(Velocity)和时间步长(delta_time)。
  • 输出:无(直接修改AGVState)。
  • 功能:根据当前速度和时间步长,更新AGV的位姿。
使用示例:
  • 在main函数中,首先设置了AGV的参数和初始状态。
  • 指定了期望的线速度和角速度,然后使用逆运动学计算需要的轮速。
  • 通过一个循环,模拟了AGV在指定轮速下的运动,每次迭代更新AGV的位姿并输出当前状态。
注意事项:
  • 该代码假设AGV在理想条件下运行,没有考虑轮滑、摩擦等因素。
  • 为了模拟连续运动,使用了时间步长delta_time,在实际应用中应根据控制器的更新频率调整。
  • 为了保持朝向角theta在−π到π之间,添加了角度归一化的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值