cmvr-head-client/cpp/common/curve/include/s_curve.h

168 lines
4.9 KiB
C
Raw Normal View History

2026-08-05 16:42:59 +08:00
//
// Created by lgv on 2026/3/2.
//
/**
* @file s_curve.h
* @brief S 线
*
* 7 S 线
* 1.
* 2.
* 3. 0
* 4.
* 5.
* 6.
* 7. 0
*
* profile
*/
#pragma once
#include <algorithm>
#include <cmath>
#include <vector>
namespace cmvr
{
/**
* @brief S 线
*/
struct SCurveProfile
{
// 7 个阶段的持续时间
double t1; // 加加速度上升时间(加速阶段)
double t2; // 匀加速时间
double t3; // 加加速度下降时间(加速阶段结束)
double t4; // 匀速时间(巡航)
double t5; // 加加速度下降时间(减速阶段)
double t6; // 匀减速时间
double t7; // 加加速度上升时间(减速阶段结束)
double total_time;
// 运动约束
double j_max; // 最大加加速度 (rad/s³)
double a_max; // 最大加速度 (rad/s²)
double v_max; // 最大速度 (rad/s)
// 运动参数
double distance; // 运动总距离
double direction; // +1 或 -1
double v_cruise; // 实际达到的巡航速度
double a_limit; // 实际达到的加速度上限
// 初始条件
double p0; // 初始位置
double v0; // 初始速度
double a0; // 初始加速度
double vf; // 终止速度
SCurveProfile()
: t1(0), t2(0), t3(0), t4(0), t5(0), t6(0), t7(0)
, total_time(0)
, j_max(50.0), a_max(10.0), v_max(3.0)
, distance(0), direction(1.0), v_cruise(0), a_limit(0)
, p0(0), v0(0), a0(0), vf(0)
{}
};
/**
* @brief S 线
*/
class SCurve
{
public:
/**
* @brief
* @param max_velocity (rad/s)
* @param max_acceleration (rad/s²)
* @param max_jerk (rad/s³)
*/
SCurve(double max_velocity = 3.0,
double max_acceleration = 10.0,
double max_jerk = 50.0);
/**
* @brief
*/
void setConstraints(double max_velocity, double max_acceleration, double max_jerk);
/**
* @brief
*/
void getConstraints(double& max_velocity, double& max_acceleration, double& max_jerk) const;
/**
* @brief S 线
* @param start_position
* @param end_position
* @param start_velocity 0
* @param end_velocity 0
* @return
*/
SCurveProfile calculateProfile(double start_position, double end_position,
double start_velocity = 0.0, double end_velocity = 0.0);
/**
* @brief t
* @param profile S 线
* @param t
* @return t
*/
double getPositionAtTime(const SCurveProfile& profile, double t) const;
/**
* @brief t
* @param profile S 线
* @param t
* @return t
*/
double getVelocityAtTime(const SCurveProfile& profile, double t) const;
/**
* @brief t
* @param profile S 线
* @param t
* @return t
*/
double getAccelerationAtTime(const SCurveProfile& profile, double t) const;
/**
* @brief t
* @param profile S 线
* @param t
* @return t
*/
double getJerkAtTime(const SCurveProfile& profile, double t) const;
/**
* @brief
* @param profile S 线
* @param dt
* @param positions
* @param velocities
* @param accelerations
*/
void generateTrajectory(const SCurveProfile& profile, double dt,
std::vector<double>& positions,
std::vector<double>& velocities,
std::vector<double>& accelerations) const;
private:
double max_velocity_;
double max_acceleration_;
double max_jerk_;
static constexpr double EPSILON = 1e-9;
static constexpr double VELOCITY_THRESHOLD = 1e-6;
double computeSegmentJerk(const SCurveProfile& profile, double t) const;
void calculateShortProfile(SCurveProfile& profile) const;
void calculateLongProfile(SCurveProfile& profile) const;
};
} // namespace cmvr