Fanuc 运动控制代码 点击:71 | 回复:2



wxwangyan12

    SSI ļʱ
发表于:2024-09-12 15:14:14
楼主
参考运动库


***********************************************************************************************
* The MotPGLib is a library of path generations functions.  It can either be called from
* simulink or hand coded C routines on the motion module.
*                                                  
* $Id: MotPGLib.c,v 1.3 2011/10/12 22:00:42 wlm Exp $  
*          
*        
**********************************************************************************************/    
/*`============================================================================
*` Included Files
*`============================================================================*/
#include "MotPGLib.h"           /* Main Include file for file */
#include "MOTPGCSolver.h"       /* Include complex solvers as needed */
#include "MathConstants.h"      /* General math constants .. PI, N1d3 , etc */

/* #define SIMULATION (1)*/  /* UNDEFINE THIS TO GET BEST PERFORMANCE ON A POWERPC and Take out Negative Test Case CMD IDs */
#ifdef SIMULATION
    #include "rt_nonfinite.h"
#else
    #include "PathGen_rt_nonfinite.h"
#endif

#include "copyright.h"                            
#include "system.h"


/*lint -esym(578, index) Suppress "Declaration of symbol 'index' hides symbol 'index" */
/*lint -esym(578, time)  Suppress "Declaration of symbol 'time' hides symbol 'time"   */

/*`============================================================================
*` CONSTANT Definitions
*`============================================================================*/
/*`============================================================================
*` STRUCTURE Definitions
*`============================================================================*/
/*============================================================================
* ENUMERATION Definitions
*============================================================================*/
/* Move Modes */
#define PGUNKNOWN   (-1)  /* Unable to find a move mode FATAL */
#define PGATCMD     (1)   /* Move at commanded values */
#define PGDECEL     (2)   /* Move Requires Deceleration to reach end conditions */
#define PGCONSTANT  (3)   /* Move requires constant velocity to reach end conditions */
#define PGACCEL     (4)   /* Move requires acceleration to reach end conditions */
#define PGSTOPACCEL (5)   /* Move requires a stop followed by an accel to reach end conditions */
#define PGMINMOVE   (6)   /* Move too small to plan */
#define PGSTOP      (7)   /* Stop Immediate non positional move required */
/* AccelDecel Nums */

#define PGDECS12      (1)       /* Accel/Decel from segment 1 or 2 */
#define PGDECS357     (2)       /* Accel/Decel from segment 3, 5 or 7 */
#define PGDECS6       (3)       /* Accel/Decel from Segement 6 */
#define PGDECSM1      (4)       /* Accel/Decel case where we are outside the segments and are acceling to get back to seg 1 */
#define PGDECDWBH     (5)       /* Initial conditions such that we need to wait until we get to where we can decel Dont worry be happy */
#define PGDECDONE     (6)       /* At constant velocity and done  */
#define PGDECERR      (-2)      /* Too many decel cases selected .. error */
#define PGDECUNKNOWN  (-1)      /* Unknown decel case */
/* NOT USED See Above  #define SIMULATION (1)  */        /* UNDEFINE THIS TO GET BEST PERFORMANCE ON A POWERPC and Take out Negative Test Case CMD IDs */
#define PGNUMPATHS (15)         /* Make equal to the number of KPP paths */
#undef UNUSED_CODE              /* Used to remove obsolete or otherwise unused code */


/*
* NOTE Structure forroot solvers
*/
union special {
    /*    uint64_T nan_uint; */
    unsigned long long nan_uint;
    real_T  nan_real;
} mynan;

/*============================================================================
* MACRO Definitions
*============================================================================*/
#define SIGN(val) (((val) > 0) ? 1 : ((val) < 0) ? -1 : 0)

#ifdef SIMULATION
  #define PGfabs(x)    ( ( (x) < 0.0 ) ? -1.0*(x) : (x) )
#else
/*  fabs_fast: This function can be used in place of fabs().
* The compiler does not use the fabs instruction. This function directly
* uses the assembly instruction and provides a replacement for the C libaray
* function, fabs(). The condition register is modified, so "cc" goes in the
* 'clobbered' list */
  #define PGfabs fabs_fast
#endif

/*lint -esym(652, round) Suppress "#define of symbol 'round(double)' declared previously at ..." */
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))

/*`============================================================================
*` Global Variables
*`============================================================================*/
real_T FTolNum;              /* Test dynamic Floating point tolerances */
real_T FTolComp;

/* Floating Point Tolerance Tables */
#define FPTolTableSize 43


/* double NumBin[37]={2<<1,2<<2,2<<3,2<<4,2<<5,2<<6,2<<7,2<<8,2<<9,2<<10,2<<11,2<<12,2<<13,2<<14,2<<15,2<<16,2<<17,2<<18,2<<19,2<<20,2<<21,
2<<22,2<<23,2<<24,2<<25,2<<26,2<<27,2<<28,2<<29,2<<30,2<<31,2<<32,2<<33,2<<34,2<<35,2<<36,2<<37} ; */
static double NumBin[FPTolTableSize]={.015625,.03125, .0625, .125, .25, .5 , 1, 2, 4, 8, 16, 32, 64, 128, 256, 512,
         1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
         8388608.0, 1677721.0, 33554432.0, 67108864.0, 134217728.0, 268435456.0, 536870912.0, 1073741824.0, 2147483648.0, 4294967296.0, 8589934592.0,
         17179869184.0, 34359738368.0, 68719476736.0};

/* 2^-(52-exponent) */
/* double Span[37]={1/(2<<51),1/(2<<49),1/(2<<48),1/(2<<47),1/(2<<46),1/(2<<45),1/(2<<44),1/(2<<43),1/(2<<42),1/(2<<41),1/(2<<40),1/(2<<39),
1/(2<<38),1/(2<<37),1/(2<<36),1/(2<<35),1/(2<<34),1/(2<<33),1/(2<<32),1/(2<<31),1/(2<<30),1/(2<<29),1/(2<<28),1/(2<<27),
1/(2<<26),1/(2<<25),1/(2<<24),1/(2<<23),1/(2<<22),1/(2<<21),1/(2<<20),1/(2<<19),1/(2<<18),1/(2<<17),1/(2<<16),1/(2<<15)}; */
static double Span[FPTolTableSize]={3.46944695195361e-018,6.93889390390723e-018,13.8777878078145e-018, 27.7555756156289e-018, 55.5111512312578e-018 ,111.022302462516e-018, 222.044604925031e-018,
         444.089209850063e-018, 888.178419700125e-018, 1.77635683940025e-015, 3.55271367880050e-015, 7.10542735760100e-015,
         14.2108547152020e-015, 28.4217094304040e-015, 56.8434188608080e-015, 113.686837721616e-015, 227.373675443232e-015,
         454.747350886464e-015, 909.494701772928e-015, 1.81898940354586e-012, 3.63797880709171e-012, 7.27595761418343e-012,
         14.5519152283669e-012, 29.1038304567337e-012, 58.2076609134674e-012, 116.415321826935e-012, 232.830643653870e-012,
         465.661287307739e-012, 931.322574615479e-012, 1.86264514923096e-009, 3.72529029846191e-009, 7.45058059692383e-009,
         14.9011611938477e-009, 29.8023223876953e-009, 59.6046447753906e-009, 119.209289550781e-009, 238.418579101563e-009,
         476.837158203125e-009, 953.674316406250e-009, 1.90734863281250e-006, 3.81469726562500e-006, 7.62939453125000e-006,
         15.2587890625000e-006};



#ifdef NUM11INTERCOOL
/* Contains the current sample number for the current command for that path.  Used by the speedup
* algos to determine when to do accel only calc and then the decel calcs.  i.e. first time through
* we only do accel calcs .. next time the decel calc for next sample period and save in our memory
* .. sample period after that we do the decel calc for the curren next sample period .. This yields
* the two decel calcs we need i.e. current sample and next sample to make a deceleration decision
* and are ready to make a deceleration decision.
*/
static real_T CurMovSample[PGNUMPATHS]={0.0};  
#endif

/*`============================================================================
*` FUNCTION Declarations
*`============================================================================*/

static real_T PGSignfast(real_T NumIn);

static boolean_T PGAtMaxVel(real_T vi, real_T VMax, real_T ai);

static void PGCheckMaxAccelDecelJerk(real_T JerkCmd,boolean_T JerkInPercent,real_T AMax,real_T DMax,
                                     real_T VMax,real_T Ai,real_T Vi,real_T Vf,real_T ts,real_T *JerkCmdAccel,
                                     real_T *JerkCmdDecel, int8_T *ErrorIDPtr);

#ifdef UNUSED_CODE
static void PGDetermineSign(real_T Si,real_T vi,real_T ai,const CmdInBus *CmdIn,real_T V3Last,
                            MaxCmdBus *MaxVarPtr);
#endif

#ifdef UNUSED_CODE
static void PGDetermineSignStop(real_T vi,real_T ai,const CmdInBus *CmdIn,real_T V3Last,MaxCmdBus *MaxVarPtr);
#endif

static boolean_T PGSameSideZero(real_T In1, real_T In2);

static boolean_T PGSameSideZeroGT(real_T In1, real_T In2);

static void PGCalcTime2SegExtT1T3JerkUUS3(real_T V0,real_T VMax,real_T A0,real_T AMax,real_T Jerk,real_T SGN,
                                          real_T J3Prior,real_T *t1Ptr,real_T *t2Ptr,real_T *t3Ptr,real_T *J1Ptr,
                                          real_T *J3Ptr, real_T *J3ModPtr, int8_T *ErrorIDPtr);

static void PGCalcTime2SegT1T3JerkUUS3(real_T V0,real_T VMax,real_T A0,real_T AMax,real_T Jerk,real_T SGN,
                                       real_T J3Prior,real_T *t1Ptr,real_T *t2Ptr,real_T *t3Ptr,real_T *J1Ptr,
                                       real_T *J3Ptr,real_T *J3ModPtr,int8_T *ErrorIDPtr);

static void PGCalcAccelMoveJ1NEJ3UUS3(real_T ai,real_T vi,real_T  AMax,real_T DMax,real_T VMax,real_T JerkCmd,
                                      real_T SGN,real_T J3Prior,real_T VMaxPrior,real_T V3Prior,real_T J5,real_T *a1Ptr,
                                      real_T *a2Ptr,real_T *a3Ptr,real_T *t1Ptr,real_T *t2Ptr,real_T *t3Ptr,
                                      real_T *J1Ptr,real_T *J3Ptr,real_T *J5_OPtr,int8_T *ErrorIDPtr);

static boolean_T PGStopped(real_T A0, real_T V0);

static void PGCalcAccelMoveJ1EQJ3UUS3(real_T ai,real_T vi,const MaxCmdBus *MaxVarPtr,real_T J3,
                                      const SegmentBus *SegmentPtr, const SegmentBus *SegmentPriorPtr,
                                      real_T *a1Ptr, real_T *a2Ptr, real_T *a3Ptr, real_T *t1Ptr,
                                      real_T *t2Ptr, real_T *t3Ptr, real_T *J1Ptr, real_T *J3Ptr,
                                      int8_T *ErrorIDPtr);

static void PGCalcAbsTime(real_T *SegTimePtr, real_T time, real_T *SegAbsTimePtr);

static void PGPlanAccelCmd(const CmdInBus *CmdInBusPtr,const CmdOutBus *PathStatePtr,SegmentBus *SegmentPriorPtr,
                           real_T timeOldMove, real_T ts, SegmentBus **SegmentPPtr,
                           real_T *timeMovePtr, int8_T *ErrorIDPtr, boolean_T *ErrorFlagPtr,
                           boolean_T *WarningFlagPtr);

static boolean_T PGCheckforMinMove(real_T Ai,real_T Vi,real_T Si,real_T Sf,real_T J3,real_T J5,
                                   real_T AMax,real_T DMax,real_T VMax, boolean_T NewPlan, real_T ts, int8_T *ErrorMinMoveChkPtr);

static int8_T PGDetermineMoveMode(real_T Ai,real_T Vi,real_T Si,real_T Vf,real_T Sf,real_T VMax,real_T AMax,real_T DMax,
                                  real_T J3,real_T J5,real_T SGN,real_T ts,boolean_T CmdDone,boolean_T NewPlan,
                                  int8_T CmdID,real_T Ji);

static void PGCalcEndCondMove(CmdOutBus CmdOutLast, real_T SampleTime, CmdOutBus *CmdOutPtr);

static void PGCalcDecelPath(real_T time, SegmentBus *SegmentpPtr,real_T SampleTime,CmdOutBus *CmdOutPtr, int8_T *ErrorID);

static boolean_T PGToleranceCheck(real_T x, real_T y, real_T  tolerance);

static real_T PGCalcPos(real_T t, real_T Pi, real_T Vi, real_T Ai, real_T Jerk);

static real_T PGCalcVel(real_T t, real_T Vi, real_T Ai, real_T Jerk);

static real_T PGCalcAccel(real_T t, real_T Ai, real_T Jerk);

static void PGGenPathTimeCap(real_T time,SegmentBus *SegmentPtr,CmdInBus *CmdBusPtr,
                             boolean_T NewPlan, real_T SampleTime,CmdOutBus *CmdOutLastPtr,
                             int8_T MoveModeOldNum, DecelCalcsBus *PriorDecelCalcsPtr,
                             CmdOutBus **CmdOutPPtr, int8_T *MoveModeNumPtr, SegmentBus **Segment_0PPtr,
                             DecelCalcsBus **CurDecelCalcsPPtr);

static void PGAssignJerkSign(real_T Vi, real_T Vf, real_T J3, real_T J5,real_T *J3Ptr, real_T *J5Ptr);

static boolean_T PGCalcCmdRejectDis(real_T Vi,real_T Si,real_T S7, real_T Ai,const MaxCmdBus *MaxVarPtr,
                                    real_T J5, real_T J3,real_T SGN);

static void PGCalcAccelPath(real_T time, const SegmentBus *SegmentPtr,real_T SampleTime,
                            CmdOutBus *CmdOutAccPtr, int8_T *RegPtr);

static void PGDecelSeg12UUS3(real_T Vi,real_T Si,real_T S7,real_T Ai,const MaxCmdBus *MaxVarPtr,real_T J3,
                             real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,real_T *t7Ptr,real_T *J5pPtr,
                             real_T *V3Ptr,real_T *errorPtr);

static boolean_T PGTestDecelSolution(real_T DMax,real_T A0,real_T V0,real_T VMax);

static void PGCompV3toVFDecelNow(real_T Ai,real_T Vi,real_T VF,real_T J3,boolean_T *V3GTVFPtr,real_T *V3cPtr);

static int8_T PGDetermineDecelNum(real_T Ai,real_T Vi,real_T Vf,real_T DMax,real_T AMax,real_T VMax,real_T J3);

static boolean_T PGSameSideZeroGTEq(real_T In1, real_T In2);

static real_T PGCheckJ3Sign(real_T Ai, real_T DMax, real_T J3);

static void quarticRoots(real_T c4, real_T c3, real_T c2, real_T c1,real_T c0, real_T roots[4]);

static void PGCalcValuesNoSeg3(real_T Vi,real_T Si,real_T S7,real_T Ai,const MaxCmdBus *MaxVarPtr,real_T J5,
                               real_T *t3Ptr, real_T*t5Ptr, real_T *t6Ptr, real_T *t7Ptr, real_T *J5pPtr,
                               real_T *V3Ptr,real_T *errorPtr);

static void PGCalcValuesNoSeg3J5EqJ7(real_T Vi,real_T Si,real_T  S7,real_T Ai,const MaxCmdBus *MaxVarPtr,
                                     real_T J3,real_T J5,real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,
                                     real_T *t7Ptr,real_T *J5pPtr,real_T *V3Ptr,real_T *errorPtr);

static void PGCalcDecelTimeNoLim(real_T Vi,real_T Si, real_T S7,real_T Ai,MaxCmdBus *MaxVarPtr,real_T J3,
                                 real_T J5,real_T ts,real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,real_T *t7Ptr,
                                 real_T *J3Ptr, real_T *J5pPtr, real_T *J7pPtr, real_T *V3Ptr, real_T *errorPtr,
                                 int8_T *ErrorIDPtr);

static void PGCheckBackup(real_T A0,real_T V0,real_T VMax,real_T DMax,real_T SGN,real_T J3,real_T J5n,real_T J5,
                          real_T errorn,real_T J5n1,real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,real_T *t7Ptr,
                          real_T *V3pPtr,real_T *J3pPtr,real_T *J5pPtr,real_T *J7pPtr,boolean_T *BackUpPtr,
                          boolean_T *StopPtr,int8_T *errorPtr);

static void PGCalcTimeToDecelJerkUUS3(const CmdOutBus *CmdOutLastPtr,const CmdInBus *CmdBusPtr,MaxCmdBus *MaxVarPtr,
                                      real_T J3, real_T J5,real_T ts,boolean_T NewPlan,const CmdOutBus *CmdOutAccPtr,
                                      DecelCalcsBus *CurDecelCalcsPtr,real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,
                                      real_T *t7Ptr,boolean_T *BackUpPtr,real_T *J3Ptr,real_T *J5Ptr,
                                      real_T *J7Ptr,real_T *V3Ptr,boolean_T *StopPtr,DecelCalcsBus *NextDecelCalcsPtr,
                                      int8_T *ErrorIDPtr);

static void PGCalcAccelVel(real_T *JPtr,const real_T *tPtr,real_T V4,real_T Vi,real_T Ai,real_T *VPtr,
                           real_T *APtr, int8_T *errorPtr);

static void PGAccelSeg12UUS3(real_T Vi,real_T Si,real_T S7,real_T Ai,const MaxCmdBus *MaxVarPtr,
                             real_T J3,real_T SGN, real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,
                             real_T *t7Ptr, real_T *J5pPtr,real_T *V3Ptr, real_T *errorPtr);

static void PGCalcTime2SegAccelJerkUUS3(real_T Ai,real_T Vi,real_T V7f,real_T Si,real_T S7,real_T SGN,
                                        real_T DMax, real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,real_T *t7Ptr,
                                        real_T *a5nPtr,real_T *J5pPtr,real_T *errorPtr);

static void PGCalcTime3SegAccelJerkUUS3(real_T Ai, real_T Vi, real_T V7f, real_T Si, real_T S7,
                                                                                real_T SGN, real_T DMax, real_T *t5Ptr, real_T *t6Ptr,
                                                                                real_T *t7Ptr, real_T *J5pPtr, real_T *errorPtr);

static void PGCalcTime2SegT6T7JerkUUS3(real_T J5,real_T Ai,real_T Vi,real_T V7f,real_T Si,real_T S7,
                                       real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,real_T *t7Ptr,real_T *V3Ptr,
                                       real_T *J7Ptr,real_T *error);

static void PGCalcValuesAccelNoSeg31(real_T Vi,real_T Si, real_T S7,real_T Ai,const MaxCmdBus *MaxVarPtr,
                                     real_T J5, real_T SGN,real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,
                                     real_T *t7Ptr,real_T *J5pPtr,real_T *V3Ptr,real_T *errorPtr);

static void PGCalcTimeToAccelJerkUUS3(const CmdOutBus *CmdOutLastPtr,const CmdInBus *CmdBusPtr,const MaxCmdBus *MaxVarPtr,
                                      real_T J3,real_T J5, real_T ts,boolean_T NewPlan,const CmdOutBus *CmdOutAccPtr,
                                      const DecelCalcsBus *CurDecelCalcsPtr,real_T *t3Ptr,real_T *t5Ptr,real_T *t6Ptr,
                                      real_T *t7Ptr,real_T *J3pPtr,real_T *J5pPtr,real_T *J7pPtr,real_T *V3pPtr,
                                      boolean_T *StopPtr,DecelCalcsBus *NextDecelCalcsPtr,boolean_T *CmdRejectPtr,
                                      int8_T *ErrorIDPtr);

static void PGCalcDecelSegments(const CmdInBus *CmdBusPtr,const CmdOutBus *CmdOutLastPtr,real_T *SegTimepPtr,
                                const real_T *SegJerkpPtr,real_T Reg,real_T time,real_T V3p,real_T VFinal,
                                real_T *PPtr, real_T *VpPtr,real_T *ApPtr,real_T *TPtr,real_T *TAbsPtr, boolean_T *BackUpPtr,
                                int8_T *ErrorIDPtr);

static void PGCheckDecelerate(const CmdOutBus *CmdOutLastPtr,const CmdInBus *CmdBusPtr,MaxCmdBus MaxVar,
                              real_T time, const real_T *SegJerkAccPtr, real_T Reg, real_T SampleTime,
                              boolean_T NewPlan, const CmdOutBus *CmdOutAccPtr, DecelCalcsBus *CurDecelCalcsPtr,
                              SegmentBus *SegmentpDecPtr, boolean_T *StopPtr, boolean_T *BackUpPtr,
                              DecelCalcsBus *NextDecelCalcsPtr,int8_T *ErrorIDPtr);

wxwangyan12

级别: 实习会员
精华主题: 0
发帖数量: 4 个
工控威望: 11 点
下载积分: 214 分
在线时间: 0(小时)
注册时间: 2024-09-02
最后登录: 2024-09-12
查看wxwangyan12的 主题 / 回贴
1楼 发表于: 10天前
 
/*` Function Definitions   **************************************************/
/*`                                                                         */

/*`*************************************************************************
*` Function:       mot_pathgen
*`
*` Description:    Invokes the motion engine to do path generation for an
*`                 axis and path. Multiple paths (2) can exist on a single
*`                 axis. They are computed independently with mot_pathgen.
*`
*` Inputs:         axis_index - specifies the axis to process
*`                 path_id - specifies the path_id
*`                 pos_err_limit - Informs the path planner of the current
*`                     state of position error. TRUE results in "pausing"
*`                     the path planner
*`
*` Outputs:        velocity, acceleration, and position values into the
*`                     data structure specified by axis_id and path_id
*`                 *error_id - pointer to an error code to be passed to the
*`                     caller. See fb_errorid.h for error codes.
*`
*` Returns:        scode - indicates a successful or failed operation.
*`                     A SUCCESS value denotes one of multiple states:
*`                 DONE - pathgen has successfully reached the end of its path
*`                 NO_ERROR - pathgen has encountered no errors and has not yet
*`                     completed its path
*`                 WARNING - pathgen has encountered a non-critical situation
*`                     in which it must pass a warning to the FB via *error_id
*`                 ERROR - pathgen has encountered a critical error in which
*`                     it must pass a warning to the FB via *error_id
*`
*`                 Valid scodes are further defined and described in
*`                     mot_subsystem.h
*`
*`**************************************************************************/
scode mot_pathgen(uint16_t axis_index,                                   /*`*/
    uint16_t path_id,                                                    /*`*/
    boolean pos_err_limit,                                               /*`*/
    uint16_t *error_id_ptr)                                              /*`*/
{
    /* $$$WORK_TODO: flm - temp pointer is not needed until we go back to using
     *  pointer swapping rather than data copy...see WORK_TODO below.
    AxisBus *AxBus_temp_ptr;
    */
    #ifdef BUILD_WITH_PERFORMANCE_DATA_CAPTURE
          UINT64 ticStart_Mot = gefTB64Get();
    #endif
    
    bool backup_allowed;
    sint8 path_num;
    
    /*` Initialize status code                                              */
    scode status=MOT_SOK_NO_ERROR;
    

    /*` Validate error_id pointer                                           */
    if (RARELY(error_id_ptr == NULL)) {
        /*` If NULL, log an internal error with ERR, return failure SCODE   */
        ERR_log_new_event(EVENTID_SOFTWARE_SYSTEM_ERROR,
                          MAKE_EVENTID_INFO(EVENT_MODID,ERR_ERROR,axis_index),
                          MAKE_EVENTID_DATA_LINENUM_SCODE(MOT_SFAIL_NULL_PTR));                        
        return MOT_SFAIL_NULL_PTR;
    }


    #if MOT_PATHGEN_DEBUG      /*save new commands to pathgen into the debug log */
        if (pathgen_input[axis_index][path_id].exec == true) {
            pg_cmdlog[pg_cmdlog_index].command = pathgen_input[axis_index][path_id].cmd_in.CmdID;
            pg_cmdtime[pg_cmdlog_index] =    ceil(TB64_TICS_TO_MSECS(TB64_GET_TICS));
            pg_axNum[pg_cmdlog_index] = axis_index;    
            pg_cmdlog[pg_cmdlog_index].commanded_position = pathgen_input[axis_index][path_id].cmd_in.Pos;
            pg_cmdlog[pg_cmdlog_index].commanded_velocity = pathgen_input[axis_index][path_id].cmd_in.Vel;
            pg_cmdlog[pg_cmdlog_index].commanded_accel = pathgen_input[axis_index][path_id].cmd_in.Accel;
            pg_cmdlog[pg_cmdlog_index].commanded_decel = pathgen_input[axis_index][path_id].cmd_in.Decel;
            pg_cmdlog[pg_cmdlog_index].jerk = pathgen_input[axis_index][path_id].cmd_in.Jerk;
            pg_cmdlog[pg_cmdlog_index].jerk_units = pathgen_input[axis_index][path_id].cmd_in.JerkUnit;
            pg_cmdlog[pg_cmdlog_index].final_velocity = pathgen_input[axis_index][path_id].cmd_in.FinalVel;            
            pg_cmdlog[pg_cmdlog_index].first_sample_period = pathgen_input[axis_index][path_id].sample_time;            
            pg_cmdlog_index ++;
            if (pg_cmdlog_index >=NUM_PGCMDS_TO_LOG){
                pg_cmdlog_index %= NUM_PGCMDS_TO_LOG;
            }

            if (pg_cmdlog_numrecdmoves < NUM_PGCMDS_TO_LOG){
                pg_cmdlog_numrecdmoves ++;
            }
        }
    #endif

    /* Determine whether to allow backups based on direction limits of the axis   */            
    /* Exceptions - The KPP can reject a new command when disallowed backups      */
    /*      prevents it from succeeding. There are cases (e.g. MC_SetPosition)    */
    /*      where this is not acceptable (KPP rejecting the command after act psn */
    /*      has been set is bad). To ensure that the command succeeds, we tell    */
    /*      KPP to allow backups on the first sample in these scenarios (below):  */
    /*   1) If forced no backups (by something like a MC_JogAxis), allow backups  */
    /*      on the first sample and thereafter force disallow backups.            */
    /*   2) Allow backups on the first sample after after executing SetPosition   */
    /*      and thereafter employ the axes' direction limits.                     */
    
    /* Note that these execptions use the "exec" flag and the fact that it is     */
    /* only true on the first sample of a new KPP cmd                             */
    if (pathgen_input[axis_index][path_id].force_no_backup)
    {
        if (pathgen_input[axis_index][path_id].exec)
        {
            backup_allowed = true;  /* Allow backups on the first sample of JogAxis */
        }
        else
        {
            backup_allowed = false; /* Thereafter, disallow backups */
        }
    } else if ((pathgen_input[axis_index][path_id].cmd_in.CmdID == pg_change_pos) && (pathgen_input[axis_index][path_id].exec))
    {
        backup_allowed = true;      /* Allow backups on the first sample of SetPsn  */
    }
    else
    {
        backup_allowed = (mot_axis_state[axis_index].path_planning[path_id].negative_direction_enabled &&
                          mot_axis_state[axis_index].path_planning[path_id].positive_direction_enabled);
    }
    
    /* Generate a unique path number for KPP */
    path_num = (axis_index + NUM_SUPPORTED_AXES*path_id);                      

    /* Update history log if one is active */  // todo stk init kpp_history log
    if (RARELY(kpp_HistoryLog[axis_index][path_id] != NULL))
    {
        if (pathgen_input[axis_index][path_id].exec == true) {
            motion_UTL_addHistoryReal64(kpp_HistoryLog[axis_index][path_id], MOT_HIST_NEW_CMD1,
                    pathgen_input[axis_index][path_id].cmd_in.Pos,
                    pathgen_input[axis_index][path_id].cmd_in.Vel);
            motion_UTL_addHistoryReal64(kpp_HistoryLog[axis_index][path_id], MOT_HIST_NEW_CMD2,
                    pathgen_input[axis_index][path_id].cmd_in.Accel,
                    pathgen_input[axis_index][path_id].cmd_in.Decel);
            motion_UTL_addHistoryReal64(kpp_HistoryLog[axis_index][path_id], MOT_HIST_NEW_CMD3,
                    pathgen_input[axis_index][path_id].cmd_in.Jerk,
                    pathgen_input[axis_index][path_id].cmd_in.FinalVel);
            motion_UTL_addHistory(kpp_HistoryLog[axis_index][path_id], MOT_HIST_NEW_CMD4,
                           (uint32_t)pathgen_input[axis_index][path_id].cmd_in.CmdID, /*lint !e571  Suppress "Suspicious cast" */
                           (uint32_t)pathgen_input[axis_index][path_id].cmd_in.JerkUnit,
                           (uint32_t)backup_allowed,0);
        }                      
    }

    /*` Step the pathgenerator one cycle with given inputs                  */
    PGPathGen(&pathgen_input[axis_index][path_id].cmd_in, /*CmdInBus *CmdInBusNewPtr,*/
              pathgen_input[axis_index][path_id].sample_time, /*real_T SampleTime,*/
              pathgen_input[axis_index][path_id].exec, /*   boolean_T NewCmd,*/
              pos_err_limit,  /*          boolean_T PosErrLim,*/
              pathgen_input[axis_index][path_id].AxisIn_ptr,        /*AxisBus *AxisInPtr,*/
              path_num,                                       /* int8_T AxisNum*/
              backup_allowed,                                 /* boolean_T BackUpAllowed*/
              pathgen_input[axis_index][path_id].AxisOut_ptr,/* AxisBus *AxisOutPtr, */
              &pathgen_input[axis_index][path_id].new_plan); /* boolean_T *NewPlanPtr)*/
            
            
    
/*    pathgen_input[axis_index][path_id].AxisBus_Even = pathgen_input[axis_index][path_id].AxisBus_Odd;*/

    /* Update the path planning info parameter */
    SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.new_cmd = pathgen_input[axis_index][path_id].exec;
    if (pathgen_input[axis_index][path_id].exec == true) {
        /* If the command is a pathgen reset, don't record the command id since the command id is stale */
        if(pathgen_input[axis_index][path_id].cmd_in.CmdID != pg_reset){
            if (pathgen_input[axis_index][path_id].cmd_in.CmdID == pg_change_pos){
                SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.command_id = MC_SET_POSITION;
            }else{
                SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.command_id = (uint16_t)(mot_axis_state[axis_index].path_planning[path_id].command);
            }
        }    
        SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.pg_cmd_id = pathgen_input[axis_index][path_id].cmd_in.CmdID & 0x7; /* only 3 bits */  
    }
    SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.new_plan = pathgen_input[axis_index][path_id].new_plan;
    SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.backing_up = pathgen_input[axis_index][path_id].AxisOut_ptr->BackUpPend;
    SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.pg_error_id= (sint8) 0;

    /*`  Reset the new command flag since we've executed the path gen.  If it was a new command, it isn't anymore. */
    pathgen_input[axis_index][path_id].exec = false;
    /*`  Reset the sample period time in case it was altered for a delayed start move */
    pathgen_input[axis_index][path_id].sample_time = MOT_SAMPLE_PERIOD_IN_SEC;

    /*` Store output commands into local command store                      */
    pathgen_output[axis_index][path_id].position = pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.Pos;
    pathgen_output[axis_index][path_id].velocity = pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.Vel;
    pathgen_output[axis_index][path_id].acceleration = pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.Accel;
    pathgen_output[axis_index][path_id].jerk = pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.Jerk;

    /*` Check if PathGen has completed its path                             */
    if ((pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.Done == true)&&(pathgen_input[axis_index][path_id].AxisOut_ptr->BackUpPend == false)) {
        SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.cmd_done = true;
        status = MOT_SOK_DONE;
    }else {
        SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.cmd_done = false;
    }
    
    
    /*` Check if PathGen had warnings and set proper error_id               */

    if (pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.Warning == true) {
        uint8_t err_severity = ERR_WARNING;
        status = MOT_SOK_WARNING;
        SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.pg_error_id = (sint8) pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.ErrorID;

        switch (pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.ErrorID){
            case KPP_ERR_BackUpRequired:
                *error_id_ptr = EVENTID_BACKUP_WARNING;
                break;
            /* For the following KPP warnings, log an event but do not propagate to the FB */
            case KPP_ERR_MaxVelEqFinVelNoSamp:         /* 31 */
            case KPP_ERR_MinMove4Seg1TsPErr:           /* 40 */
            case KPP_ERR_MinMove4Seg1TsVErr:           /* 41 */
            case KPP_ERR_Long_Move_Warning:            /* 60 */
            case KPP_ERR_AccelJerkLimMaxVel:           /* 124 */             /* Warnings that indicate jerk was internally reduced */
            case KPP_ERR_DecelJerkLimMaxVel:           /* 125 */          
            case KPP_ERR_MaxJerkAccelOneSample:        /* 126 */
            case KPP_ERR_MaxJerkDecelOneSample:        /* 127 */
                *error_id_ptr = EVENTID_NON_ERROR_PMM_EVENT;
                err_severity = ERR_INFORMATIONAL;      /* Log event in event queue, not IO fault table */
                status = MOT_SOK_NO_ERROR;             /* Don't signal to FSM that we've encountered a warning */
                break;
                
            default:
                *error_id_ptr = EVENTID_JERK_WARNING;
                break;
                
        }
        
        /*log a warning*/
        ERR_log_new_event(*error_id_ptr,
                          MAKE_EVENTID_INFO(EVENT_MODID,err_severity,axis_index),
                          MAKE_EVENTID_DATA_LINENUM_16BITDATA(pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.ErrorID));                        
    }
    /*` Check if PathGen had errors and set proper error_id                 */
    if (pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.Error == true) {
        uint8_t err_severity = ERR_ERROR;
        status = MOT_SOK_ERROR;
        
        SYS_module_data_store.axis[axis_index].path_plan_info.path_plan_info_bits.pg_error_id = (sint8) pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.ErrorID;
        switch (pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.ErrorID){
            case KPP_ERR_NotDis2Accel2EC:
                *error_id_ptr = EVENTID_CANNOT_ACCEL_TO_END_COND;
                break;
            case KPP_ERR_NotDis2Accel2EC1:
                *error_id_ptr = EVENTID_CANNOT_REACH_VEL_AT_POS;
                break;
            /* KPP Errors that require a normal stop: */    
            case KPP_ERR_UnknownCmdID:                  
            case KPP_ERR_ErrFloatTol:
            case KPP_ERR_BadCaseTimCapGenPath:
            case KPP_ERR_NotValidBlendFinalVel:
            case KPP_ERR_DirNotAllowed:
                *error_id_ptr = EVENTID_AXIS_NORMAL_STOPPED;
                break;
            case KPP_ERR_NoAccelSolnCC3:
                *error_id_ptr = EVENTID_MOT_JERK_TOO_SMALL;
                break;
            case KPP_ERR_MinMoveAccelMGDecel:
                *error_id_ptr = EVENTID_MOT_ACC_EXCEEDS_DEC;
                break;
            case KPP_ERR_OVERMAXACCELTIME:
                *error_id_ptr = EVENTID_MOT_OVER_MAX_ACCEL_TIME;
                break;
            case KPP_ERR_OVERMAXDECELTIME:
                *error_id_ptr = EVENTID_MOT_OVER_MAX_DECEL_TIME;
                break;
            case KPP_ERR_NoBackUpAllowed:  
                /* Note we give special handling to the case where backups are explicitly  *
                 * disallowed (e.g. we are Jogging). Ignore backup errors from the KPP.    */
                if (pathgen_input[axis_index][path_id].force_no_backup){
                    err_severity = ERR_INFORMATIONAL;
                }
                *error_id_ptr = EVENTID_MOT_NO_BACKUP_ALLOWED;
                break;
            case KPP_ERR_InitCondBlendNA:
                *error_id_ptr = EVENTID_MOT_CANT_BLEND_INIT_CONDS;
                break;
            default:
                /*All others - fast stop the axis */
                *error_id_ptr = EVENTID_MOT_UNRECOVERABLE_CALCULATION_ERR;
                break;
        }

        /* Log the error.                                                      *
         * To decode the internal KPP error, convert the last 8 bits of the    *
         * event extra data to a 2C signed integer. The error or warning code  *
         * is listed (in decimal) in MotPGLib.h.                               */
        ERR_log_new_event(*error_id_ptr,
                          MAKE_EVENTID_INFO(EVENT_MODID,err_severity,axis_index),
                          MAKE_EVENTID_DATA_LINENUM_16BITDATA(pathgen_input[axis_index][path_id].AxisOut_ptr->CmdOut.ErrorID));                        

    }

    /* Copy AxisOut to AxisIn */
    /*  $$$WORK_TODO: flm - swapping the pointers is causing pathgen to produce
     * bad results.  For the moment, we remove the pointer swap and copy the data (below).
     * The copy costs about 14usec, so when pathgen has been fixed to handle the
     * pointer swap, put this code back and take out the copy below.
    AxBus_temp_ptr = pathgen_input[axis_index][path_id].AxisIn_ptr;
    pathgen_input[axis_index][path_id].AxisIn_ptr = pathgen_input[axis_index][path_id].AxisOut_ptr;
    pathgen_input[axis_index][path_id].AxisOut_ptr = AxBus_temp_ptr;
    */
    
    *pathgen_input[axis_index][path_id].AxisIn_ptr = *pathgen_input[axis_index][path_id].AxisOut_ptr;

    #ifdef BUILD_WITH_PERFORMANCE_DATA_CAPTURE
          SYS_module_data_store.module_parms.perf_params.p9121_p9125_mot_fsm_pathgen[axis_index].execTimeWords.execTime2 = gefTB64Get() - ticStart_Mot;
    #endif

    /*` Return the status of processing of this function                    */
    return status;
}

wxwangyan12

级别: 实习会员
精华主题: 0
发帖数量: 4 个
工控威望: 11 点
下载积分: 214 分
在线时间: 0(小时)
注册时间: 2024-09-02
最后登录: 2024-09-12
查看wxwangyan12的 主题 / 回贴
2楼 发表于: 10天前
 
/**` \file cam_build_profile.c
*`*************************************************************************************
*` Routines needed to build cam profiles. Building a cam profile consists primarily
*` of generating the coefficients needed by CAM_commandGen, but also includes setting
*` some initial values of the profile (from MC_CamTableSelect inputs).    
*`
*` ##############################################################################
*` # IMPORTANT! The algorithms in this module are documented in "PACMotion:
*` # Curve-Fitting Algorithms for Cams" (hereafter CFAC). This file is stored as
*` # a supplementay document to the Cam Subsystem design.
*` ##############################################################################                                                      
*`                                                                                            
*` $Id: cam_build_profile.c,v 1.2.4.1 2012/04/23 20:36:57 skandl Exp $                                                                                                                              
*`*************************************************************************************/

/* Unit-testing can be turned on and off here, but release builds will always
* have it off */
/*//#ifdef DEBUG_BUILD*/
#undef CAM_BUILD_PROFILE_UT
/*//#endif*/

#ifdef CAM_BUILD_PROFILE_UT
#include "stdio.h"
#endif

/*lint +libh(cam_subsystem.h) make lint ignore what it thinks is mutliple inclusion */

/*`============================================================================
*` Included Files
*`============================================================================*/
#include <math.h>               /*`*/
#include "cmd.h"                /*`*/
#include "utl.h"                /*`*/
#include "cam_subsystem.h"      /*`*/
#include "cam_manager.h"        /*`*/
#include "cam_build_profile.h"  /*`*/  
#include "cam_command_gen.h"    /*`*/
#include "fb_errorid.h"         /*`*/
#include "module_ids.h"         /*`*/
/*============================================================================
* CONSTANT Definitions
*============================================================================*/
#define EVENT_MODID CAM_BUILD_PROFILE_MODID

/*============================================================================
* MACRO Definitions
*============================================================================*/
/*` Size of the scratch arrays. At this time, this number will track the maximum
*` number of points that are allowed in cubic splines since they need the most
*` space to compute */
#define CAM_TEMP_ARRAYS_SIZE    (4096) /*`*/

/*============================================================================
* SCALAR TYPE Definitions
*============================================================================*/

/*` Scratch arrays used to do calculations */
static real64 x_tmp[CAM_TEMP_ARRAYS_SIZE];
static real64 y_tmp[CAM_TEMP_ARRAYS_SIZE];
static real64 b_tmp[CAM_TEMP_ARRAYS_SIZE];
static real64 c_tmp[CAM_TEMP_ARRAYS_SIZE];
static real64 d_tmp[CAM_TEMP_ARRAYS_SIZE];

/*============================================================================
* ENUMERATION Definitions
*============================================================================*/
/**
* boundary - somewhat arbitrarily, the left side is the START and
*            and the right side is the END */
typedef enum boundary {
    START = 1,
    MIDDLE,
    END
} boundary_t;

/**
* quad_opts - boundary value options for quadratic splines
* */
typedef enum quad_opts {
    QUAD_START_AUTO,
    QUAD_START_1STDER,
    QUAD_START_2NDDER,
    QUAD_END_AUTO,
    QUAD_END_1STDER,
    QUAD_END_2NDDER,
    QUAD_PERIODIC
} quad_opts_t;

/**
* cubic_opts - boundary value options for cubic splines
* */
typedef enum cubic_opts {
    CUBIC_INVALID,      /* not a valid selection */
    CUBIC_AUTO_AUTO,
    CUBIC_AUTO_1STDER,
    CUBIC_AUTO_2NDDER,
    CUBIC_1STDER_AUTO,
    CUBIC_1STDER_1STDER,
    CUBIC_1STDER_2NDDER,
    CUBIC_2NDDER_AUTO,
    CUBIC_2NDDER_1STDER,
    CUBIC_2NDDER_2NDDER,
    CUBIC_PERIODIC
} cubic_opts_t;

/*============================================================================
* STRUCTURE Definitions
*============================================================================*/
/* None */

/*`============================================================================
*` FUNCTION Declarations
*`============================================================================*/

/*` spline2build: Builds all quadratic sectors in a profile */
STATIC void spline2build(profile_t *profilePtr, uint32_t perm);

/*` spline2OneSector: Builds the special case of one quadratic sector */
STATIC scode spline2OneSector(profile_t *profilePtr, sector_t *secPtr, bool periodic);
              
/*` spline2MultiSector: Builds multiple quadratic sectors */    
STATIC scode spline2MultiSector(profile_t *profilePtr, uint32_t perm, \
                    uint32_t firstSectorNum, uint32_t lastSectorNum, \
                    uint32_t size, bool periodic);
                    
/*` spline2CrossBound: [Only periodic profiles] Builds quadratic sectors
*` when they wrap around the boundary. */
STATIC scode spline2CrossBound(profile_t *profilePtr, uint32_t perm, \
                    uint32_t highSectorNum, uint32_t lowSectorNum, \
                    uint32_t highSize, uint32_t lowSize);

/*` spline3build: Builds all cubic sectors in a profile */
STATIC void spline3build(profile_t *profilePtr, uint32_t perm);

/*` spline3OneSector: Builds the special case of one cubic sector */
STATIC scode spline3OneSector(profile_t *profilePtr, sector_t *secPtr, bool periodic);

/*` spline3MultiSector: Builds multiple cubic sectors */
STATIC scode spline3MultiSector(profile_t *profilePtr, uint32_t perm, \
                    uint32_t firstSectorNum, uint32_t lastSectorNum, \
                    uint32_t size, bool periodic);
                    
/*` spline3CrossBound: [Only periodic profiles] Builds cubic sectors
*` when they wrap around the boundary. */
STATIC scode spline3CrossBound(profile_t *profilePtr, uint32_t perm, \
                    uint32_t highSectorNum, uint32_t lowSectorNum, \
                    uint32_t highSize, uint32_t lowSize);

/*` setCubeBoundaryOption: sets boundaries for non-peridoic profiles that have
*` cubic FIRST AND LAST sectors. */
STATIC cubic_opts_t setCubeBoundaryOption(profile_t *profilePtr);

/*` Provides a boundary value when none has been given. */
STATIC real64 autoSetDer(real64 *x,real64 *y,uint32_t n, boundary_t side); /*`*/

/*` Generates coefficents for a linear curve fit. */
STATIC void linear(real64 *x, real64 *y, uint32_t n, real64 *b); /*`*/

/*` Generates coefficents for a Quadratic Spline curve fit. */
STATIC scode spline2(real64 *x, real64 *y, real64 bound,
                    quad_opts_t opts, int32_t n,
                    real64 *b, real64 *c); /*`*/

/*` spline3: This function generates coefficents for a Cubic Spline curve fit. */
STATIC scode spline3(real64 *x, real64 *y, real64 strt_bound,
                        real64 end_bound, cubic_opts_t opts, int32_t n,
                        real64 *b, real64 *c, real64 *d);

/*` spline5: This function generates coefficents for a Quintic Spline curve fit. */
STATIC void spline5(real64 *x,real64 *y, uint32_t n,
        real64 *b, real64 *c, real64 *d, real64 *e, real64 *f);
                    
/*============================================================================
* VARIABLE Definitions
*============================================================================*/
/* None */

/*`============================================================================
*` FUNCTION Definitions
*`============================================================================*/

/**
*`***************************************************************************
*` camProfileBuild: Builds the specified permutation of the given profile. Fills
*`                 in the coefficients for the permutation. The cam file must
*`                 have been unpacked into the profile structure and the sectors
*`                 and coefficient pointers must already be set up. Any maximum
*`                 number of sectors or points must be checked elsewhere, as this
*`                 function will try to build any profile it's given.
*`
*` \param[in,out] profilePtr
*`                 Contains the profile and instance with data from the unpacked
*`                 cam file.
*`
*` \param in permutation
*`                 Indicates the permutation of the profile to build. This
*`                 permutation MUST be in the BUILDING state, or no coefficents
*`                 will be created.
*`
*` \return scode
*`
*` Go through the profile instance by curve-fit types.
*` - First, generate coefficients for completly specified sectors
*` (i.e. invarient end-conditions) linear and quintic-splines with 1st
*` and 2nd derivatives specified.
*` - Second, generate coefficients for quadratic-splines (1 free end-condition).
*` - Finally, generate coefficients for cubic-splines (2 free end-conditions).
*` - Indicate that the profile has been built to CMD and internally
*`**************************************************************************/
scode camProfileBuild(profile_t *profilePtr, uint8_t permutation) /*`*/
{
    scode status = CAM_SOK;
    uint32_t i, ofst;
    profileInstance_t *piPtr;  /* Pointer to the instance to build coefs for */
    real64 *xPtr, *yPtr;
    sector_t *sPtr;
    
    /*` IF NULL input */
    if( NULL == profilePtr) {
        /*` Log Error */
        status = CAM_NULL_INPUT;        
        ERR_log_new_event(EVENTID_INTERNAL_SW_STATUS_ERROR,
                          MAKE_EVENTID_INFO(EVENT_MODID,ERR_ERROR,MODULE_INDEX),
                          MAKE_EVENTID_DATA_LINENUM_SCODE(status));              
    }
    /*` ELSE IF permutation is too big */
    else if (MAX_INST_PERMS <= permutation) {
        status = CAM_FATAL_ERROR;        
        ERR_log_new_event(EVENTID_INTERNAL_SW_STATUS_ERROR,
            MAKE_EVENTID_INFO(EVENT_MODID,ERR_ERROR,MODULE_INDEX),
            MAKE_EVENTID_DATA_LINENUM_SCODE(permutation));  
    }
    /*` ELSE */
    else {
        /*` Set up some local pointers */
        piPtr = profilePtr->camInstArr[permutation];
        xPtr = profilePtr->x;
        yPtr = profilePtr->y;
        /*` IF profile instance pointer is not NULL */
        if(piPtr != NULL) {
            /*` IF profile instance state is not built */
            if(NOT_BUILT == piPtr->state) {
                
                /*`***********************************************************
                 *`  Linear and quitic sectors are complete (i.e. they do not
                 *` have user-definable boundary conditions), which is why
                 *` they can be built without the additional functions that
                 *` the quadratic and cubic functions have.
                 *`***********************************************************/
                
                /*` Build Linear Sectors */
                for(i=0; i < profilePtr->numOfSectors; i++) {
                    if(piPtr->secPtr.curve_fit_type == LINEAR_FIT) {
                        ofst = piPtr->secPtr.table_location;
                        sPtr = &(piPtr->secPtr);
                        /* If this is not the last sector, leave the size alone
                         * Else, this is the last sector, subtract one from the
                         * size. */
                        if (i != profilePtr->numOfSectors-1) {
                            linear(&xPtr[ofst],&yPtr[ofst],sPtr->size,sPtr->b);
                        }
                        else {
                            linear(&xPtr[ofst],&yPtr[ofst],sPtr->size-1,sPtr->b);
                        }
                    }
                }
                /*` Build Quintic Sectors (of deficiency 3) */
                for (i=0; i < profilePtr->numOfSectors; i++) {
                    if (piPtr->secPtr.curve_fit_type == QUINTIC_SPLINE) {
                        ofst = piPtr->secPtr.table_location;
                        sPtr = &(piPtr->secPtr);
                        /* If this is not the last sector, leave the size alone
                         * Else, this is the last sector, subtract one from the
                         * size. */
                        if (i != profilePtr->numOfSectors-1) {
                            spline5(&xPtr[ofst], &yPtr[ofst], sPtr->size, sPtr->b,
                                sPtr->c, sPtr->d, sPtr->e, sPtr->f);
                        }
                        else {
                            spline5(&xPtr[ofst], &yPtr[ofst], sPtr->size-1, sPtr->b,
                                sPtr->c, sPtr->d, sPtr->e, sPtr->f);
                        }
                    }
                }
                /*` Build Quadratic Sectors */
                for(i=0; i < profilePtr->numOfSectors; i++) {
                    if(piPtr->secPtr.curve_fit_type == QUAD_SPLINE) {
                        /*` If one QUAD_SPLINE found, build all quads */
                        spline2build(profilePtr, permutation);
                        break;
                    }
                }
                
                /*` IF build not aborted */
                if(BUILD_ABORTED != piPtr->state) {
                    /*` Build Cubic Sectors */
                    for(i=0; i < profilePtr->numOfSectors; i++) {
                        if(piPtr->secPtr.curve_fit_type == CUBIC_SPLINE) {
                            /*` If one CUBIC_SPLINE found, build all cubics */
                            spline3build(profilePtr, permutation);
                            break;
                        }
                    }
                } /*` ENDIF */
            }
            /*` ENDIF */
            
            /*` Building all done */
            /*` IF aborted build */
            if(BUILD_ABORTED == piPtr->state) {
                /*` Set the status */
                status = CAM_PROFILE_BUILD_FAILED;
                /* Already been logged where state was set */
            }
            /*` Else */
            else {                        
                /*` Set state to BUILT */
                piPtr->state = BUILT;
            }
            /*` ENDIF */
        }
        /*` ELSE */
        else{
            /*` Log Error, b/c profile instance is null */
            status = CAM_UNEXPECTED_PATH;
            ERR_log_new_event(EVENTID_INTERNAL_SW_STATUS_ERROR,
                              MAKE_EVENTID_INFO(EVENT_MODID,ERR_ERROR,MODULE_INDEX),
                              MAKE_EVENTID_DATA_LINENUM_SCODE(status));          
        }
        /*` ENDIF */
    }
    return status;
}




楼主最近还看过

wxwangyan12

  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 0回
  • 年度积分:50
  • 历史总积分:50
  • 注册:2024年9月12日
发表于:2024-09-24 13:47:19
1楼

双Q联系人号码

172346149



技术交流沟通方式

回复本条

    

Rockymei

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 53回
  • 年度积分:32
  • 历史总积分:45
  • 注册:2007年4月13日
发表于:2024-09-26 15:03:42
2楼

下载学习一下

回复本条

    
SSI ļʱ