• 【深蓝学院】移动机器人运动规划--第5章 最优轨迹生成--作业


    0. 题目

    在这里插入图片描述

    1. 解答

    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述

    Listing1:

    void minimumJerkTrajGen(
        // Inputs:
        const int pieceNum,
        const Eigen::Vector3d &initialPos,
        const Eigen::Vector3d &initialVel,
        const Eigen::Vector3d &initialAcc,
        const Eigen::Vector3d &terminalPos,
        const Eigen::Vector3d &terminalVel,
        const Eigen::Vector3d &terminalAcc,
        const Eigen::Matrix3Xd &intermediatePositions,
        const Eigen::VectorXd &timeAllocationVector,
        // Outputs:
        Eigen::MatrixX3d &coefficientMatrix)
    {
        // coefficientMatrix is a matrix with 6*piece num rows and 3 columes
        // As for a polynomial c0+c1*t+c2*t^2+c3*t^3+c4*t^4+c5*t^5,
        // each 6*3 sub-block of coefficientMatrix is
        // --              --
        // | c0_x c0_y c0_z |
        // | c1_x c1_y c1_z |
        // | c2_x c2_y c2_z |
        // | c3_x c3_y c3_z |
        // | c4_x c4_y c4_z |
        // | c5_x c5_y c5_z |
        // --              --
        // Please computed coefficientMatrix of the minimum-jerk trajectory
        // in this function
    
        // ------------------------ Put your solution below ------------------------
        //coefficientMatrix维度维度为(6*pieceNum, 3),之前已经给出,不用操作
        //起始和末状态的PVA约束分别是3行,加起来总共6行约束(s*2s)=(3*6),中间状态有(pieceNum-1)组约束(2s*2s)=(6*6),所以总约束仍为(2sM*2sM)=(6M*6M)
        Eigen::MatrixXd M = Eigen::MatrixXd::Zero(6*pieceNum, 6*pieceNum);
        Eigen::MatrixXd b = Eigen::MatrixXd::Zero(6*pieceNum, 3);
    
        //初始条件PVA约束
        Eigen::MatrixXd F_0(3, 6);
        F_0.setZero();
        F_0(0,0) = 1;
        F_0(1,1) = 1;
        F_0(2,2) = 2;
        M.block(0,0,3,6) = F_0;
        b.row(0) = initialPos.transpose();
        b.row(1) = initialVel.transpose();
        b.row(2) = initialAcc.transpose();
    
        //终止条件条件PVA约束
        Eigen::MatrixXd E_M(3, 6);
        double T_M = timeAllocationVector(pieceNum-1);
        double T_M_2 = T_M * T_M;
        double T_M_3 = T_M_2 * T_M;
        double T_M_4 = T_M_3 * T_M;
        double T_M_5 = T_M_4 * T_M;
        E_M <<  1,  T_M,    T_M_2,  T_M_3,      T_M_4,      T_M_5,
                0,  1,      2*T_M,  3*T_M_2,    4*T_M_3,    5*T_M_4,
                0,  0,      2,      6*T_M,      12*T_M_2,   20*T_M_3;
        M.block(6*pieceNum-3,6*(pieceNum-1),3,6) = E_M;
        b.row(6*pieceNum-3) = terminalPos.transpose();
        b.row(6*pieceNum-2) = terminalVel.transpose();
        b.row(6*pieceNum-1) = terminalAcc.transpose();
    
    
        //M共pieceNum-1组中间状态约束,前面F_0的3*6 PVA约束,后面E_M的3*6 PVA约束,
        //中间是pieceNum-1组中间状态约束,由waypoint,P,V,A,Jerk,Snap连续可导组成的E_i(6*6),F_i(6*6)约束
        for(int i = 1; i < pieceNum; ++i) {//这里使用的时间是左闭右开,中间点约束在左边点上,所以是从第[1]个而非第[0]个开始
            double T = timeAllocationVector(i-1);
            double T_2 = T * T;
            double T_3 = T_2 * T;
            double T_4 = T_3 * T;
            double T_5 = T_4 * T;
            Eigen::MatrixXd E_i(6, 6);
            Eigen::MatrixXd F_i(6, 6);
            E_i <<  1,  T,  T_2,    T_3,    T_4,    T_5,
                    1,  T,  T_2,    T_3,    T_4,    T_5,
                    0,  1,  2*T,    3*T_2,  4*T_3,  5*T_4,
                    0,  0,  2,      6*T,    12*T_2, 20*T_3,
                    0,  0,  0,      6,      24*T,   60*T_2,
                    0,  0,  0,      0,      24,     120*T;
            M.block(6*i-3, 6*(i-1), 6, 6) = E_i;
    
            F_i.setZero();
            F_i(1,0) = -1;
            F_i(2,1) = -1;
            F_i(3,2) = -2;
            F_i(4,3) = -6;
            F_i(5,4) = -24;
            M.block(6*i-3, 6*i, 6, 6) = F_i;
    
            Eigen::Vector3d D_i_transpose = intermediatePositions.block(0,i-1,3,1);
            b.block(6*i-3, 0, 1, 3) << D_i_transpose(0), D_i_transpose(1), D_i_transpose(2);
    
        }
    
        clock_t time_stt = clock();
        // 使用PartialPivLU进行分解
    //    Eigen::PartialPivLU lu(M);
        // Mc = b 解为c
        std::cout << "use lu" <<std::endl;
        coefficientMatrix = M.lu().solve(b);
    
    /*    // Solve Mc = b, using QR solver
        for (int i = 0; i < 3; i++)
        {
            coefficientMatrix.col(i) = M.colPivHouseholderQr().solve(b.col(i));
    //         coefficientMatrix.col(i) = M.lu().solve(b.col(i));
        }
        coefficientMatrix = M.inverse() * b;*/
    
        // std::cout << "C is " << coefficientMatrix << std::endl;
        std::cout << "Time cost = " << 1000 * (clock() - time_stt) / (double)CLOCKS_PER_SEC << "ms" << std::endl;
    
        // ------------------------ Put your solution above ------------------------
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
  • 相关阅读:
    linux学习实操计划0102-查看系统配置和版本
    华为云云服务器评测|基于华为云云耀云服务器L实例开展性能评测,例如 MySQL、Clickhouse、Elasticsearch等等
    使用vue-cli搭建SPA项目
    Excel 自动提取某一列不重复值
    数据结构之初阶二叉树
    万字总结线程安全问题
    SpringBoot自动装配
    WinApp自动化测试之工具的选择
    Linux系统防火墙iptables
    C++中的Vector容器:动态数组的魅力
  • 原文地址:https://blog.csdn.net/qq_37746927/article/details/136153560