S型曲线规划

s

#include "stdio.h"


typedef struct S_CTRL{
#define SSPD_BUF_LEN 100
    struct{
        float aMax;
        float aMin;
        float vMax;
        float J;/* 加加速度 */
        int t[7];
        int T[7];

        int tMax;
    }in;
    struct{
        float accBuf[SSPD_BUF_LEN];
        float decBuf[SSPD_BUF_LEN];
        long  S[7];
        long  V[7];
    }out;
}S_CTRL;



S_CTRL sCR = {
        {
                .aMax = 1400000.0, /* R/Min^2 */
                .aMin = -1400000.0,/* R/Min^2 */
                .vMax = 3000.0,    /*   RPM   */
                .J = 30.0,        /* R/Min^3 */
                {
                    0
                },
                {
                        40,20,40,0,40,20,40
                    },

                .tMax = 200

        }

};

#define _T(sCTRL,i) ((sCTRL).in.T[(i)-1])
#define s (sCR)
int main(){

    float v = 0;
    float pos = 0;
    float tao = 0;
    int t1 = 40;
    int t2 = 60;
    int t3 = 100;

    sCR.in.t[0] = sCR.in.T[0];
    sCR.in.t[1] = sCR.in.T[1]+sCR.in.t[0];
    sCR.in.t[2] = sCR.in.T[2]+sCR.in.t[1];
    sCR.in.t[3] = sCR.in.T[3]+sCR.in.t[2];
    sCR.in.t[4] = sCR.in.T[4]+sCR.in.t[3];
    sCR.in.t[5] = sCR.in.T[5]+sCR.in.t[4];
    sCR.in.t[6] = sCR.in.T[6]+sCR.in.t[5];


//    sCR.in.T[0] = sCR.in.t[0]-0;
//    sCR.in.T[1] = sCR.in.t[1]-sCR.in.t[0];
//    sCR.in.T[2] = sCR.in.t[2]-sCR.in.t[1];
//    sCR.in.T[3] = sCR.in.t[3]-sCR.in.t[2];
//    sCR.in.T[4] = sCR.in.t[4]-sCR.in.t[3];
//    sCR.in.T[5] = sCR.in.t[5]-sCR.in.t[4];
//    sCR.in.T[6] = sCR.in.t[6]-sCR.in.t[5];


    for(int i=0;i<7;i++){
        printf("t[%d] = %d\n",i,sCR.in.t[i]);
    }

    float J_tmp = 0;
    J_tmp = -(sCR.in.J);
    int flag = 0;
    for(int time = 0;time<sCR.in.tMax;time++)
    {
        if(time<sCR.in.t[0]){/* T1 */
            tao = time;
            v = (sCR.in.J)*(tao)*(tao)/2;
            pos = (sCR.in.J)*tao*tao*tao/6;
            flag = 1;
        }else if(time<sCR.in.t[1]){/* T2 第二段速度文档中公式是错的 */
            if(time == sCR.in.t[0]){
                sCR.out.S[0] = (sCR.in.J)*tao*tao*tao/6;
                sCR.out.V[0] = (sCR.in.J)*(tao)*(tao)/2;
            }

            tao = time-t1;
              v = (sCR.in.J)*_T(s,1)*(_T(s,1)/2+tao);
              pos = sCR.out.S[0] + (sCR.out.V[0])*tao + (sCR.in.J)*_T(s,1)*tao*tao/2;
            flag = 2;
        }else if(time<sCR.in.t[2]){/* T3 */
            if(time == sCR.in.t[1]){
                sCR.out.S[1] = sCR.out.S[0] + (sCR.out.V[0])*tao + (sCR.in.J)*_T(s,1)*tao*tao/2;
                sCR.out.V[1] = (sCR.in.J)*_T(s,1)*(_T(s,1)/2+tao);
            }
            tao = time-t2;
            v = (sCR.in.J)*(_T(s,1)*_T(s,2)+_T(s,1)*_T(s,1)/2+_T(s,1)*tao-tao*tao/2.0);
            pos = sCR.out.S[1]+sCR.out.V[1]*tao+(sCR.in.J)*_T(s,1)*tao*tao/2-(sCR.in.J)*tao*tao*tao/6;
            flag = 3;
        }else if(time<sCR.in.t[3]){/* T4 */
            //nothing..
            if(time == sCR.in.t[2]){
                sCR.out.S[2] =  sCR.out.S[1]+sCR.out.V[1]*tao+(sCR.in.J)*_T(s,1)*tao*tao/2-(sCR.in.J)*tao*tao*tao/6;//上个位置公式的末尾速度
                sCR.out.V[2] = (sCR.in.J)*(_T(s,1)*_T(s,2)+_T(s,1)*_T(s,1)/2+_T(s,1)*tao-tao*tao/2.0);//上个速度公式的末尾速度
            }
            v = (sCR.in.J)*_T(s,1)*(_T(s,1)+_T(s,2));
            pos = sCR.out.S[2] + sCR.out.V[2]*tao;
        }else if(time<sCR.in.t[4]){/* T5 */
            if(time == sCR.in.t[3]){
                /* T4 没用到,所以这里用T3的 */
                sCR.out.S[3] = sCR.out.S[1]+sCR.out.V[1]*tao+(sCR.in.J)*_T(s,1)*tao*tao/2-(sCR.in.J)*tao*tao*tao/6;
                sCR.out.V[3] = (sCR.in.J)*(_T(s,1)*_T(s,2)+_T(s,1)*_T(s,1)/2+_T(s,1)*tao-tao*tao/2.0);
            }
            tao = time-sCR.in.t[3];
            v = (sCR.in.J)*(_T(s,1)*_T(s,1)+_T(s,1)*_T(s,2)-tao*tao/2);
            pos = sCR.out.S[3]+sCR.out.V[3]*tao-(sCR.in.J)*tao*tao*tao/6;
        }else if(time<sCR.in.t[5]){/* T6 */
            if(time == sCR.in.t[4]){
                sCR.out.S[4] = sCR.out.S[3]+sCR.out.V[3]*tao-(sCR.in.J)*tao*tao*tao/6;
                sCR.out.V[4] = (sCR.in.J)*(_T(s,1)*_T(s,1)+_T(s,1)*_T(s,2)-tao*tao/2);
            }
            tao = time-sCR.in.t[4];
            v = (sCR.in.J)*_T(s,1)*(_T(s,2)+_T(s,1)/2-tao);
            pos = sCR.out.S[4] + sCR.out.V[4]*tao-(sCR.in.J)*_T(s,1)*tao*tao/2;
        }else if(time<sCR.in.t[6]){/* T7 最后一段速度文档中公式是错的 */
            if(time == sCR.in.t[5]){
                sCR.out.S[5] = sCR.out.S[4] + sCR.out.V[4]*tao-(sCR.in.J)*_T(s,1)*tao*tao/2;
                sCR.out.V[5] = (sCR.in.J)*_T(s,1)*(_T(s,2)+_T(s,1)/2-tao);
            }
            tao = time-sCR.in.t[5];
//            v = (sCR.in.J)*(T1*T2+T1*T1/2-T1*tao+tao*tao/2);
              v = (sCR.in.J)*(_T(s,1)*_T(s,2)+_T(s,1)*_T(s,1)/2-(_T(s,1)*_T(s,6))-_T(s,1)*tao+tao*tao/2);
              pos = sCR.out.S[5]+sCR.out.V[5]*tao-(sCR.in.J)*_T(s,1)*tao*tao/2+(sCR.in.J)*tao*tao*tao/6;
        }


//        sCR.out.accBuf[time] = v;
//        printf("v[%d]%d=%f\n",time,flag,v);
//        printf("%d->%f\n",time,v);
//        printf("%f\n",v);
        printf("%f\n",pos);
    }

    return 0;
}

















在这里插入图片描述

内容概要:本文提出了一种基于融合鱼鹰算法和柯西变异的改进麻雀优化算法(OCSSA),用于优化变分模态分解(VMD)的参数,进而结合卷积神经网络(CNN)与双向长短期记忆网络(BiLSTM)构建OCSSA-VMD-CNN-BILSTM模,实现对轴承故障的高【轴承故障诊断】基于融合鱼鹰和柯西变异的麻雀优化算法OCSSA-VMD-CNN-BILSTM轴承诊断研究【西储大学数据】(Matlab代码实现)精度诊断。研究采用西储大学公开的轴承故障数据集进行实验验证,通过优化VMD的模态数和惩罚因子,有效提升了信号分解的准确性与稳定性,随后利用CNN提取故障特征,BiLSTM捕捉时间序列的深层依赖关系,最终实现故障类的智能识别。该方法在提升故障诊断精度与鲁棒性方面表现出优越性能。; 适合人群:具备一定信号处理、机器学习基础,从事机械故障诊断、智能运维、工业大数据分析等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①解决传统VMD参数依赖人工经验选取的问题,实现参数自适应优化;②提升复杂工况下滚动轴承早期故障的识别准确率;③为智能制造与预测性维护提供可靠的技术支持。; 阅读建议:建议读者结合Matlab代码实现过程,深入理解OCSSA优化机制、VMD信号分解流程以及CNN-BiLSTM网络架构的设计逻辑,重点关注参数优化与故障分类的联动关系,并可通过更换数据集进一步验证模泛化能力。
### FOC S曲线规划算法实现 #### 背景概述 磁场定向控制(Field-Oriented Control, FOC)是一种用于永磁同步电机(Permanent Magnet Synchronous Motor, PMSM)的高效控制策略。为了平滑启动和停止过程,通常会引入S速度曲线来减少机械冲击并提高运动精度。 在FOC控制系统中,S曲线的位置环可以通过恒定Jerk的方式实现[^1]。这种算法的特点在于其角度-时间曲线呈现S形状,而速度-时间曲线则表现为马鞍形。这有助于精确控制位置变化的时间特性。 #### 数学建模与核心原理 S曲线的核心思想是通过对加速度的变化率(即Jerk)进行限制,从而形成光滑的速度轨迹。以下是其实现的关键步骤: 1. **定义参数** 需要预先设置的目标参数包括但不限于: - 初始速度 \(v_0\) 和最终速度 \(v_f\) - 加速度极限 \(a_{max}\) - 减速度极限 \(-a_{min}\) - Jerk极限 \(J_{max}\) 2. **计算阶段划分** 整个运动分为三个主要部分:加速区、匀速区以及减速区。当目标位移较大时可能存在匀速区间;反之,则仅存在加速和减速两个区域[^3]。 3. **总位移验证** 使用公式推导出理论上的总位移 \(L\) 并将其与实际需求对比。如果发现无法达到预设的最大速度,则需调整该值并通过数值方法如二分查找找到合适的替代方案。 4. **离散化处理** 将连续函数转换成适合嵌入式设备执行的形式——例如利用表格存储关键点数据以便快速检索访问[^1]。 #### C语言伪代码示例 下面给出一段简单的C程序框架作为参考: ```c #include <stdio.h> #include <math.h> // 定义结构体保存路径信息 typedef struct { double t_start; double v_max; } PathInfo; PathInfo plan_s_curve(double s_target, double a_max, double j_max); int main() { double target_displacement = 10.0; // 单位: 米 double max_acceleration = 2.0; // 单位: m/s² double jerk_limit = 0.5; // 单位: m/s³ PathInfo result = plan_s_curve(target_displacement, max_acceleration, jerk_limit); printf("Start Time:%f\nMax Velocity:%f", result.t_start, result.v_max); return 0; } PathInfo plan_s_curve(double s_target, double a_max, double j_max) { const double tolerance = 1e-6; double low_v = 0.0, high_v = sqrt(s_target * abs(j_max)); while (fabs(high_v - low_v) > tolerance){ double mid_v = (low_v + high_v)/2.; // 计算对应于当前尝试速度下的全程所需距离 double temp_L = pow(mid_v/j_max , 3)*j_max/3.; if(temp_L >=s_target ){ high_v=mid_v ; }else{ low_v=mid_v ; } } PathInfo res={sqrt(low_v /abs(j_max)),low_v}; return res; } ``` 此段代码展示了如何运用二分搜索技术寻找最接近理想状况的实际可行最高行驶速率,并据此构建完整的行程计划。 #### 结论 综上所述,在FOC架构下应用S曲线能够显著改善动态响应品质,降低振动噪声等问题的发生概率。通过合理配置各项物理量限幅标准并与具体应用场景相结合,可进一步提升整体性能表现。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值