/* * Created: 2022/11/4 11:02:40 * Author: wangzk zhengmengxing */ #include "..\PrjCommon\CommonDef.h" #include "..\PrjCommon\DevDefine.h" #include "AttMath.h" #include "AttCtrlMain.h" //extern sAttPriData * m_pZKPriInfo; /************************************************ 说明:初始化参数,进程开始调用一次 输入:pCtlPara:控制参数结构 返回 : ************************************************/ void ZKPosCtlInit(void) { sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; AttCtrlConst_t *tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; //sAttOrbitCtlInfo_t *pOrbCtrl; //sAttCtlPara_t *pWCtrl; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; //tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; if((NULL==tmpAtt) || (NULL==tmpConst)) {return;} //pOrbCtrl = &tmpAtt->sOrbitInp; //pWCtrl=&tmpAtt->sCtlPara; //pOrbCtrl->CurOrbCtrlPcak_ReceiveFlg = 0x00; //磁控相关参数初始化 //PD控制算法参数初始化 //tmpConst->AttCmdFlashPara.kp_ToSun_PD[0] = 2.6832f; //tmpConst->AttCmdFlashPara.kp_ToSun_PD[1] = 3.1585f; //tmpConst->AttCmdFlashPara.kp_ToSun_PD[2] = 1.3033f; //tmpConst->AttCmdFlashPara.kd_ToSun_PD[0] = 58.694f ; //tmpConst->AttCmdFlashPara.kd_ToSun_PD[1] = 69.0921f ; //tmpConst->AttCmdFlashPara.kd_ToSun_PD[2] = 22.8084f ; //tmpConst->AttCmdFlashPara.w0max_PD = 0.1f * ANG2RADIAN; tmpConst->AttCmdFlashPara.kp_ToSun_PD[0] = 0.98064f; tmpConst->AttCmdFlashPara.kp_ToSun_PD[1] = 1.1544f; tmpConst->AttCmdFlashPara.kp_ToSun_PD[2] = 0.773f; tmpConst->AttCmdFlashPara.kd_ToSun_PD[0] = 27.0464f ; tmpConst->AttCmdFlashPara.kd_ToSun_PD[1] = 31.8378f ; tmpConst->AttCmdFlashPara.kd_ToSun_PD[2] = 13.388f ; tmpConst->AttCmdFlashPara.w0max_PD = 0.1f * ANG2RADIAN; tmpConst->kp_NoToSun_PD[0] = 0.6949f; tmpConst->kp_NoToSun_PD[1] = 2.6546f; tmpConst->kp_NoToSun_PD[2] = 3.2654f; tmpConst->kd_NoToSun_PD[0] = 7.6008f ; tmpConst->kd_NoToSun_PD[1] = 29.0342f ; tmpConst->kd_NoToSun_PD[2] = 35.7145f ; tmpConst->w0max_NoPD = 0.2f * ANG2RADIAN; tmpConst->PDNo_Ts = 0.2f; tmpConst->AttCmdFlashPara.PD_Ts = 3.0f; //PID控制算法参数初始化 //tmpConst->AttCmdFlashPara.kp_PID[0] = 2.6832f; //tmpConst->AttCmdFlashPara.kp_PID[1] = 3.1585f; //tmpConst->AttCmdFlashPara.kp_PID[2] = 1.3033f; //tmpConst->AttCmdFlashPara.kd_PID[0] = 58.694f; //tmpConst->AttCmdFlashPara.kd_PID[1] = 69.0921f; //tmpConst->AttCmdFlashPara.kd_PID[2] = 22.8084f; //tmpConst->AttCmdFlashPara.ki_PID[0] = 0.0008f; //tmpConst->AttCmdFlashPara.ki_PID[1] = 0.0009f; //tmpConst->AttCmdFlashPara.ki_PID[2] = 0.0002f; //tmpConst->AttCmdFlashPara.w0max_PID = 0.1f * ANG2RADIAN; tmpConst->AttCmdFlashPara.kp_PID[0] = 0.98064f; tmpConst->AttCmdFlashPara.kp_PID[1] = 1.1544f; tmpConst->AttCmdFlashPara.kp_PID[2] = 0.773f; tmpConst->AttCmdFlashPara.kd_PID[0] = 27.0464f; tmpConst->AttCmdFlashPara.kd_PID[1] = 31.8378f; tmpConst->AttCmdFlashPara.kd_PID[2] = 13.388f; tmpConst->AttCmdFlashPara.ki_PID[0] = 0.0004f; tmpConst->AttCmdFlashPara.ki_PID[1] = 0.0004f; tmpConst->AttCmdFlashPara.ki_PID[2] = 0.0002f; tmpConst->AttCmdFlashPara.w0max_PID = 0.1f * ANG2RADIAN; //tmpConst->kp_NoPID[0] = 0.5; //tmpConst->kp_NoPID[1] = 2.2; //tmpConst->kp_NoPID[2] = 3.6; //tmpConst->kd_NoPID[0] = 5.0; //tmpConst->kd_NoPID[1] = 25.9; //tmpConst->kd_NoPID[2] = 42.2; //tmpConst->ki_NoPID[0] = 0.0008; //tmpConst->ki_NoPID[1] = 0.0009; //tmpConst->ki_NoPID[2] = 0.0002; tmpConst->kp_NoPID[0] = 0.6949f; tmpConst->kp_NoPID[1] = 2.6546f; tmpConst->kp_NoPID[2] = 3.2654f; tmpConst->kd_NoPID[0] = 7.6008f; tmpConst->kd_NoPID[1] = 29.0342f; tmpConst->kd_NoPID[2] = 35.7145f; tmpConst->ki_NoPID[0] = 0.0002f; tmpConst->ki_NoPID[1] = 0.0008f; tmpConst->ki_NoPID[2] = 0.0009f; tmpConst->w0max_NoPID = 0.20f * ANG2RADIAN; tmpConst->PIDNo_Ts = 0.2f; tmpConst->AttCmdFlashPara.PID_Ts = 4.0f; //飞轮控制参数 //tmpConst->Whl_J[0] = 0.0064; //tmpConst->Whl_J[1] = 0.0064; //tmpConst->Whl_J[2] = 0.0064; //tmpConst->Whl_J[3] = 0.0064; //memset(pWCtrl->WheelCtrlResultPre, 0, 3*sizeof(TYPE_CAL)); } /************************************************ 说明:初始化参数,每周期调用一次 输入:pCtlPara:控制参数结构 ************************************************/ void ZKPosCtlOutInit(void) { sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; sAttCtlPara_t *pWCtrl =NULL; if(NULL == tmpAtt) {return;} pWCtrl=&tmpAtt->sCtlPara; //控制指令 memset(pWCtrl->Mag_DeltBb, 0.0, 3*sizeof(TYPE_CAL)); memset(pWCtrl->WheelCtrlResult, 0.0, 3*sizeof(TYPE_CAL)); } /*********************************************** 说明:磁速率计算 ***********************************************/ //Bdot=当前拍-上一拍磁矢量 void MagDataDeltaProc(TYPE_CAL *cMagBb, TYPE_CAL *cMagBbPre, TYPE_CAL *cMagDelta, TYPE_CAL cDeltaT) { UINT32 i = 0; if(POSE_ABSF(cDeltaT) >POSE_ZERO) { for (i = 0; i < 3; ++i) { cMagDelta[i] = (cMagBb[i] - cMagBbPre[i]) / cDeltaT; } } } /*********************************************** //磁控速率阻尼算法 ***********************************************/ void CtrlMagBdotDamp(TYPE_CAL *cDeltBb, TYPE_CAL *cMagT) { UINT8 i =0; TYPE_CAL tmpBdot[3] = { 0.0 }; sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; AttCtrlConst_t *tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; //tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; if((NULL==tmpAtt) || (NULL==tmpConst)) {return; } memcpy( tmpBdot, cDeltBb, 12 ); for (i = 0; i < 3; ++i) { /* 死区处理*/ if ((cDeltBb[i] > -POSE_ABSF(tmpConst->Mag_DampBdotMin)) && (cDeltBb[i] < POSE_ABSF(tmpConst->Mag_DampBdotMin))) { tmpBdot[i] = 0; } else { ; } //cMagT[i] = -tmpConst->Mag_Bb_CtrlMax * ((float)CalPFlag(tmpBdot[i])); if (tmpBdot[i]>POSE_ZERO) { cMagT[i] = -tmpConst->Mag_Bb_CtrlMax; } else if (tmpBdot[i]Mag_Bb_CtrlMax; } else { cMagT[i] = 0; } } } //选择计算Bdot的方式\计算磁控阻尼控制力矩 void MagDmpMomentCal(void) { UINT32 tmpCNT = 0; sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; //AttCtrlConst_t *tmpConst; MagPara_t *PMag =NULL; sAttCtlPara_t *pWCtrl =NULL; sAttDeterPara_t*pDeter =NULL; MagPara_t *pMag =NULL; //sAttEnvPara_t *pEnv; MtPara_t *pMt =NULL; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; if(NULL == tmpAtt) {return;} //tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; PMag = &tmpAtt->sPerPara.MagPara; pWCtrl=&tmpAtt->sCtlPara; pDeter=&tmpAtt->sDeterPara; pMag=&tmpAtt->sPerPara.MagPara; //pEnv = &tmpAtt->sEnvPara; pMt=&tmpAtt->sPerPara.MtPara; //tmpCNT = pMt-> MTCtrlTime % tmpConst->MTCtrlClc; tmpCNT = pMt-> MTCtrlTime % 10; if ((POSE_NO != PMag->Mag_Use ) && (POSE_NO != pDeter->Wi_Vld)) { if ((1 == tmpCNT)||( 0x88 == pMag->MagUseSwich)) { cross( &PMag->Mag_Bb[0], &pDeter->Wi[0], &pWCtrl->Mag_DeltBb[0] ); CtrlMagBdotDamp( pWCtrl->Mag_DeltBb, pWCtrl->MagCtrlResult); } } else if ((POSE_NO != PMag->Mag_Use ) && (POSE_NO != PMag->Mag_UsePre)) { if ((1 == tmpCNT)||(0x88 == pMag->MagUseSwich)) { /* 使用前后拍差来计算Bdot */ //MagDataDeltaProc(PMag->Mag_Bb, PMag->Mag_BbPre, &(pWCtrl->Mag_DeltBb[0]),tmpConst->Mag_BdotltaT ); MagDataDeltaProc(PMag->Mag_Bb, PMag->Mag_BbPre, &(pWCtrl->Mag_DeltBb[0]),5.0f ); CtrlMagBdotDamp( pWCtrl->Mag_DeltBb, pWCtrl->MagCtrlResult); } } else { pWCtrl->MagCtrlResult[0] = 0.0f; pWCtrl->MagCtrlResult[1] = 0.0f; pWCtrl->MagCtrlResult[2] = 0.0f; } //printf("--FL1--\n"); } //磁控对日控制算法 void MagSunMomentCal(void) { UINT32 tmpCNT = 0; UINT32 i = 0; UINT32 k = 0; UINT8 tempM1OK = POSE_OK; TYPE_CAL tempXb[3] = { 1.0f , 0.0f , 0.0f }; TYPE_CAL tempDt[3] = { 0.0F , 0.0F , 0.0F }; TYPE_CAL tempN[3] = { 0.0F , 0.0F , 0.0F }; TYPE_CAL tempA = 0.0f; TYPE_CAL tempAlpha = 0.0f; TYPE_CAL tempB = 0.0f; TYPE_CAL tempBeta = 0.0f; TYPE_CAL tempTXB[3] = { 0.0F , 0.0F , 0.0F }; TYPE_CAL tempM1[3] = { 0.0F , 0.0F , 0.0F }; TYPE_CAL tempWXB[3] = { 0.0F , 0.0F , 0.0F }; TYPE_CAL tempW0[3] = { 0.0F , 0.0F , 0.0F }; TYPE_CAL tempM2[3] = { 0.0F , 0.0F , 0.0F }; TYPE_CAL tmpDtM=0.0f; //TYPE_CAL tmpDtK1=0.05,tmpDtK2=1.0; sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; AttCtrlConst_t *tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; MagPara_t *PMag =NULL; sAttCtlPara_t *pCtrl =NULL; sAttDeterPara_t*pDeter =NULL; sAttModPara_t *pWMod =NULL; sAttCtlPara_t *pWCtrl =NULL; MagPara_t *pMag =NULL; MtPara_t *pMt =NULL; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; //tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; if((NULL==tmpAtt) || (NULL==tmpConst)) {return;} PMag = &tmpAtt->sPerPara.MagPara; pCtrl=&tmpAtt->sCtlPara; pDeter=&tmpAtt->sDeterPara; pWMod =&tmpAtt->sModePara; pWCtrl=&tmpAtt->sCtlPara; pMag=&tmpAtt->sPerPara.MagPara; pMt=&tmpAtt->sPerPara.MtPara; /*-----------------------------M1-------------------------*/ //计算Tm if (0x55 == pWMod->WModSadaOpen) { tempXb[0] = 0.0f ; tempXb[1] = 1.0f ; tempXb[2] = 0.0f ; } else { tempXb[0] = 0.0f ; tempXb[1] = 0.0f ; tempXb[2] = -1.0f ; } cross( &tempXb[0], pDeter->SunVecb , &tempDt[0] ); //计算Tn cross( &tempDt[0], &tempXb[0] , &tempN[0] ); CalNormal(tempN, 3, &tmpDtM); if(tmpDtM < POSE_ZERO) { tempM1OK = POSE_NO; } else { tempN[0] = tempN[0]/tmpDtM; tempN[1] = tempN[1]/tmpDtM; tempN[2] = tempN[2]/tmpDtM; } tmpCNT = pMt-> MTCtrlTime % 10; if ((1 == tmpCNT)||(0x88 == pMag->MagUseSwich)) { //计算期望力矩与卫星本体系磁场强度夹角, Posedot( &tempN[0], &PMag->Mag_UBb[0], 3, &tempA ); tempAlpha = POSE_ACOSF(tempA); if ((tempAlpha > tmpConst->Mag_ATTTOSUN ) && ((tempAlpha < (180.0* ANG2RADIAN-tmpConst->Mag_ATTTOSUN))&&(tmpConst->Mag_ATTTOSUN< 90.0*ANG2RADIAN))&&(POSE_OK ==tempM1OK )) { //计算卫星-Zb轴与太阳矢量夹角β Posedot( &pDeter->SunVecb[0], &tempXb[0], 3, &tempB ); tempBeta = POSE_ACOSF(tempB); //计算太阳指向控制磁矩M1 cross( &tempN[0], &PMag->Mag_Bb[0] , &tempTXB[0] ); if (pWMod->WModSadaOpen== 0x55) { tempM1[0] = tmpConst->Mag_KpFBZK[0]*tempBeta*tempTXB[0]; tempM1[1] = tmpConst->Mag_KpFBZK[1]*tempBeta*tempTXB[1]; tempM1[2] = tmpConst->Mag_KpFBZK[2]*tempBeta*tempTXB[2]; } else { tempM1[0] = tmpConst->Mag_Kp[0]*tempBeta*tempTXB[0]; tempM1[1] = tmpConst->Mag_Kp[1]*tempBeta*tempTXB[1]; tempM1[2] = tmpConst->Mag_Kp[2]*tempBeta*tempTXB[2]; } //printf("pCtrl12: %d \n", tmpCNT); } else { tempM1[0] =0.0f; tempM1[1] =0.0f; tempM1[2] =0.0f; } /*-----------------------------M2-------------------------*/ if (0x55 == pWMod->WModSadaOpen) { //tempW0[0] = pDeter->AttRateTarRe[0] ; //tempW0[1] = pDeter->AttRateTarRe[1] ; //弧度 tempW0[1] = tmpConst->Mag_FBZKWTOSUN; } else { //tempW0[2] = pDeter->AttRateTarRe[2] ; //弧度 tempW0[2] = tmpConst->Mag_WTOSUN; } cross( &tempW0[0], &PMag->Mag_Bb[0] , &tempWXB[0] ); if ((POSE_NO != PMag->Mag_Use ) && (POSE_NO != pDeter->Wi_Vld)) { cross( &PMag->Mag_Bb[0], &pDeter->Wi[0], &pWCtrl->Mag_DeltBb[0] ); for (i = 0; i < 3; ++i) { if (pWMod->WModSadaOpen== 0x55) { tempM2[i] = tmpConst->Mag_KdFBZK[i]*(pCtrl->Mag_DeltBb[i] + tempWXB[i]); } else { tempM2[i] = tmpConst->Mag_Kd[i]*(pCtrl->Mag_DeltBb[i] + tempWXB[i]); } } //printf("pCtrl12: %d \n", tmpCNT); } else if ((POSE_NO != PMag->Mag_Use ) && (POSE_NO != PMag->Mag_UsePre)) { /* 使用前后拍差来计算Bdot */ //MagDataDeltaProc(PMag->Mag_Bb, PMag->Mag_BbPre, &(pWCtrl->Mag_DeltBb[0]),tmpConst->Mag_BdotltaT ); MagDataDeltaProc(PMag->Mag_Bb, PMag->Mag_BbPre, &(pWCtrl->Mag_DeltBb[0]),5.0f ); for (i = 0; i < 3; ++i) { if (pWMod->WModSadaOpen== 0x55) { tempM2[i] = tmpConst->Mag_KdFBZK[i]*(pCtrl->Mag_DeltBb[i] + tempWXB[i]); } else { tempM2[i] = tmpConst->Mag_Kd[i]*(pCtrl->Mag_DeltBb[i] + tempWXB[i]); } } }else{;} for (k = 0; k < 3; ++k) { pCtrl->MagCtrlResult[k] = - tempM1[k] - tempM2[k]; } } //printf("pCtrl12: %d \n", tmpCNT); } /*********************************************** 说明:飞轮PD控制算法 ***********************************************/ void WheelCalc_PD(void) { TYPE_CAL tmpDeltaA[3]= {0.0}, tmpDeltaW[3]= {0.0}; UINT8 i=0; TYPE_CAL tmpTc[3]= {0.0}; TYPE_CAL tmpP[3]= {0.0}, tmpD[3]= {0.0}; TYPE_CAL tmpTs =0.0; TYPE_CAL tmpHwb[3]= {0.0}, tmpCw[12]= {0.0},tmpSJ[9]= {0.0},tmpHj[4]= {0.0}, tmpHXW[3]= {0.0},tmpHb[3]= {0.0}, tmpHIbi[3]= {0.0}; sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; AttCtrlConst_t *tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; sAttDeterPara_t *pDeter =NULL; sAttGuidLawPara_t *pGuide =NULL; sAttCtlPara_t *pCtrl =NULL; sAttModPara_t *pWMod =NULL; WhlPara_t *PWhl =NULL; TYPE_CAL tmpW0 =0.0; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; //tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; if((NULL==tmpAtt) || (NULL==tmpConst)) {return;} pDeter=&tmpAtt->sDeterPara; pGuide=&tmpAtt->sGuidLawPara; pCtrl=&tmpAtt->sCtlPara; pWMod=&tmpAtt->sModePara; PWhl = &tmpAtt->sPerPara.WhlPara; if (POSE_OK == pWMod->WModSadaOpen) { memcpy(tmpP, tmpConst->AttCmdFlashPara.kp_ToSun_PD, 3*sizeof(TYPE_CAL)); memcpy(tmpD, tmpConst->AttCmdFlashPara.kd_ToSun_PD, 3*sizeof(TYPE_CAL)); tmpW0 = tmpConst->AttCmdFlashPara.w0max_PD; tmpTs = tmpConst->AttCmdFlashPara.PD_Ts; } else { memcpy(tmpP, tmpConst->kp_NoToSun_PD, 3*sizeof(TYPE_CAL)); memcpy(tmpD, tmpConst->kd_NoToSun_PD, 3*sizeof(TYPE_CAL)); tmpW0 = tmpConst->w0max_NoPD; tmpTs = tmpConst->PDNo_Ts; } //计算惯性系下整星三轴角动量 memcpy(tmpSJ, tmpConst->SAT_J, 9*sizeof(TYPE_CAL)); memcpy(tmpCw, tmpConst->AttCmdFlashPara.M_Wheel, 12*sizeof(TYPE_CAL)); for(i=0;i<4;i++) { tmpHj[i]= PWhl->Whl_Momentum[i]; } //计算本体系飞轮角动量 MatrixProductHL(tmpCw, tmpHj, tmpHwb, 3, 4, 1); //计算惯性系下整星三轴角动量 MatrixProductHL(tmpSJ, pDeter->Wi, tmpHIbi, 3, 3, 1); for(i=0;i<3;i++) { tmpHb[i] = tmpHwb[i] + tmpHIbi[i]; } cross(tmpHb, pDeter->Wi, tmpHXW); //计算偏差角和偏差角速度 for(i=0;i<3;i++) { tmpDeltaA[i]=pDeter->CLPAttAng[i]-pGuide->TargAng[i]; DeviAngleLimit(&tmpDeltaA[i]); tmpDeltaW[i]=pDeter->CLPAttAngRat[i]-pGuide->TargAngRat[i]; } for(i=0;i<3;i++) { tmpTc[i]=tmpP[i]*tmpDeltaA[i]+tmpD[i]*tmpDeltaW[i] + tmpHXW[i]; } //限幅 for(i=0;i<3;i++) { if(POSE_ABSF(pDeter->CLPAttAngRat[i])>tmpW0) { if ((pDeter->CLPAttAngRat[i]>POSE_ZERO)&&(tmpTc[i]CLPAttAngRat[i]- tmpW0); } else if((pDeter->CLPAttAngRat[i]POSE_ZERO)) { tmpTc[i]=tmpD[i]*(pDeter->CLPAttAngRat[i]+ tmpW0); } } } //一阶惯性 for(i=0;i<3;i++) { pCtrl->WheelCtrlResult[i]=(tmpTs/(1.0f+tmpTs))*pCtrl->WheelCtrlResultPre[i]+ (1.0f/(1.0f+tmpTs))*tmpTc[i]; } //记录前次数据 memcpy(pCtrl->WheelCtrlResultPre, pCtrl->WheelCtrlResult, 3*sizeof(TYPE_CAL)); } /*********************************************** 说明:飞轮PID控制算法 ***********************************************/ void WheelCalc_PID(void) { TYPE_CAL tmpP[3] ={0.0f}, tmpD[3] ={0.0f}, tmpI[3] ={0.0f}; TYPE_CAL tmpDeltaA[3] ={0.0f}, tmpDeltaW[3] ={0.0f}; UINT8 i =0; UINT8 tmp_cnt = 0; TYPE_CAL tmpAerr[3] ={0.0f}; TYPE_CAL tmpTc[3] ={0.0f}; TYPE_CAL tmpTs =0.0f; TYPE_CAL tmpW0 =0.0f; TYPE_CAL tmpHwb[3] ={0.0f}, tmpCw[12] ={0.0f},tmpSJ[9] ={0.0f},tmpHj[4] ={0.0f}, tmpHXW[3] ={0.0f},tmpHb[3] ={0.0f}, tmpHIbi[3] ={0.0f}; sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; AttCtrlConst_t *tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; sAttDeterPara_t *pDeter =NULL; sAttGuidLawPara_t *pGuide =NULL; sAttCtlPara_t *pCtrl =NULL; sAttModPara_t *pWMod =NULL; WhlPara_t *PWhl =NULL; AttIMPTPara_t *pImpt =NULL; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; //tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; if((NULL==tmpAtt) || (NULL==tmpConst)) {return;} pDeter=&tmpAtt->sDeterPara; pGuide=&tmpAtt->sGuidLawPara; pCtrl=&tmpAtt->sCtlPara; //tmpTs=tmpConst->AttCmdFlashPara.PID_Ts; pWMod=&tmpAtt->sModePara; PWhl = &tmpAtt->sPerPara.WhlPara; pImpt=&tmpAtt->sIMPTPara; if (POSE_OK == pWMod->WModSadaOpen) { memcpy(tmpP, tmpConst->AttCmdFlashPara.kp_PID, 3*sizeof(TYPE_CAL)); memcpy(tmpD, tmpConst->AttCmdFlashPara.kd_PID, 3*sizeof(TYPE_CAL)); memcpy(tmpI, tmpConst->AttCmdFlashPara.ki_PID, 3*sizeof(TYPE_CAL)); tmpW0 = tmpConst->AttCmdFlashPara.w0max_PID; tmpTs=tmpConst->AttCmdFlashPara.PID_Ts; } else { memcpy(tmpP, tmpConst->kp_NoPID, 3*sizeof(TYPE_CAL)); memcpy(tmpD, tmpConst->kd_NoPID, 3*sizeof(TYPE_CAL)); memcpy(tmpI, tmpConst->ki_NoPID, 3*sizeof(TYPE_CAL)); tmpW0 = tmpConst->w0max_NoPID; tmpTs=tmpConst->PIDNo_Ts; } memcpy(tmpAerr, pCtrl->SumAerrPre, 3*sizeof(TYPE_CAL)); //计算惯性系下整星三轴角动量 memcpy(tmpSJ, tmpConst->SAT_J, 9*sizeof(TYPE_CAL)); memcpy(tmpCw, tmpConst->AttCmdFlashPara.M_Wheel, 12*sizeof(TYPE_CAL)); for(i=0;i<4;i++) { tmpHj[i]= PWhl->Whl_Momentum[i]; } //计算本体系飞轮角动量 MatrixProductHL(tmpCw, tmpHj, tmpHwb, 3, 4, 1); //计算惯性系下整星三轴角动量 MatrixProductHL(tmpSJ, pDeter->Wi, tmpHIbi, 3, 3, 1); //计算整星角动量 for(i=0;i<3;i++) { tmpHb[i] = tmpHwb[i] + tmpHIbi[i]; } cross(tmpHb, pDeter->Wi, tmpHXW); for (i = 0; i < WHEEL_NUM; ++i) { if ((POSE_OK == pImpt->Whl_Use[i])&&(POSE_OK == PWhl->WhlIn_Valid[i])) { if(tmp_cnt<255) {tmp_cnt++;} } } if (tmp_cnt < 3) { for(i=0;i<3;i++) { tmpHXW[i] =0.0f; } } //计算偏差角和偏差角速度 for(i=0;i<3;i++) { tmpDeltaA[i]=pDeter->CLPAttAng[i]-pGuide->TargAng[i]; DeviAngleLimit(&tmpDeltaA[i]); tmpDeltaW[i]=pDeter->CLPAttAngRat[i]-pGuide->TargAngRat[i]; tmpAerr[i]+=tmpDeltaA[i];//角度偏差积分 } memcpy(pCtrl->SumAerrPre, tmpAerr, 3*sizeof(TYPE_CAL)); //计算三轴控制指令 for(i=0;i<3;i++) { tmpTc[i]=tmpP[i]*tmpDeltaA[i]+tmpD[i]*tmpDeltaW[i]+tmpI[i]*pCtrl->SumAerrPre[i] + tmpHXW[i]; } //限幅 for(i=0;i<3;i++) { if(POSE_ABSF(pDeter->CLPAttAngRat[i])>tmpW0 ) { //printf("C: %d \n", i); if ((pDeter->CLPAttAngRat[i]>POSE_ZERO)&&(tmpTc[i]CLPAttAngRat[i]- tmpW0 ); } else if((pDeter->CLPAttAngRat[i]POSE_ZERO)) { tmpTc[i]=tmpD[i]*(pDeter->CLPAttAngRat[i]+ tmpW0); } else{;} } } //一阶惯性 for(i=0;i<3;i++) { pCtrl->WheelCtrlResult[i]=(tmpTs/(1.0f+tmpTs))*pCtrl->WheelCtrlResultPre[i]+ (1.0f/(1.0f+tmpTs))*tmpTc[i]; } //记录前次数据 memcpy(pCtrl->WheelCtrlResultPre, pCtrl->WheelCtrlResult, 3*sizeof(TYPE_CAL)); //printf("pCtrl11: %f, |%f, |%f \n", pCtrl->WheelCtrlResult[0],pCtrl->WheelCtrlResult[1],pCtrl->WheelCtrlResult[2]); //printf("pCtrl12: %f, |%f, |%f \n", pCtrl->WheelCtrlResultPre[0],pCtrl->WheelCtrlResultPre[1],pCtrl->WheelCtrlResultPre[2]); } /********************飞轮角动量计算 *****************/ void Whl_Momentum_Count(void) { UINT32 i = 0; TYPE_CAL tmpCw[12] ={0.0f}, tmpJ[4] ={0.0f}; TYPE_CAL tmpHj[4] ={0.0f}; sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; AttCtrlConst_t *tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; //sAttErrCtlPara_t *pREcheck; WhlPara_t *PWhl =NULL; //AttIMPTPara_t *pImpt; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; //tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; if((NULL==tmpAtt) || (NULL==tmpConst)) {return;} //pREcheck=&tmpAtt->sErrCtlPara; PWhl = &tmpAtt->sPerPara.WhlPara; //pImpt=&tmpAtt->sIMPTPara; //计算本体系合角动量(复用) memcpy(tmpJ, tmpConst->Whl_J, 4*sizeof(TYPE_CAL)); memcpy(tmpCw, tmpConst->AttCmdFlashPara.M_Wheel, 12*sizeof(TYPE_CAL)); //计算四个轮子的角动量 for (i = 0; i < WHEEL_NUM; ++i) { if (POSE_OK == PWhl->WhlIn_Valid[i]) { PWhl->Whl_Momentum[i] = tmpJ[i] * PWhl->Whl_Rate[i]*RPM2RADS; } else { PWhl->Whl_Momentum[i] = 0; } } ////计算卫星本体下飞轮三轴角动量 //MatrixProductHL(tmpConst->AttCmdFlashPara.M_Wheel, PWhl->Whl_Momentum, PWhl->Whl_Momentum_XYZ, 3, 4, 1);//计算本体系三轴角动量 for(i=0;i<4;i++) { tmpHj[i]= PWhl->Whl_Momentum[i] - tmpConst->Whl_HCent[i]; //tempHCent可更改 } MatrixProductHL(tmpCw, tmpHj, PWhl->Whl_Momentum_XYZ, 3, 4, 1);//计算本体系飞轮角动量 CalNormal(PWhl->Whl_Momentum_XYZ, 3, &PWhl->Whl_Momentum_Sum); } /*********************************************** 说明:磁力矩器卸载算法,卸载飞轮+星体 ***********************************************/ void CtrlWheelReleaseProc(void) { UINT8 i = 0; //TYPE_CAL tmpH[4]; TYPE_CAL tmpHwb[3] ={0.0f}; //TYPE_CAL tmpHb[3],tmpHIbi[3]; TYPE_CAL tmpk1 =0.0f,tmpk2 =0.0f; TYPE_CAL tmpModB =0.0f; TYPE_CAL tmpModH =0.0f; //TYPE_CAL tmpModHDET; TYPE_CAL tmpLamd =0.0f; TYPE_CAL tmpang =0.0f; TYPE_CAL tmpJB[3] ={0.0f}; TYPE_CAL tempBXH[3] = { 0.0F , 0.0F , 0.0F }; UINT32 tmpCNT = 0; sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; AttCtrlConst_t *tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; sAttDeterPara_t *pDeter =NULL; sAttCtlPara_t *pCtrl =NULL; sAttDataPrePara_t *pData =NULL; MagPara_t *pMag =NULL; WhlPara_t *PWhl =NULL; MtPara_t *pMt =NULL; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; //tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; if((NULL==tmpAtt) || (NULL==tmpConst)) {return;} pDeter=&tmpAtt->sDeterPara; pCtrl=&tmpAtt->sCtlPara; pData=&tmpAtt->sPerPara; pMag=&tmpAtt->sPerPara.MagPara; PWhl = &tmpAtt->sPerPara.WhlPara; pMt=&tmpAtt->sPerPara.MtPara; if(POSE_NO == pDeter->Wi_Vld) { memset(pCtrl->MagCtrlResult, 0, 3*sizeof(TYPE_CAL)); return; } tmpCNT = pMt-> MTCtrlTime % 10; if ((1 == tmpCNT)||(0x88 == pMag->MagUseSwich)) { for(i=0;i<3;i++) { tmpHwb[i] = PWhl->Whl_Momentum_XYZ[i]; } //计算三轴推力器卸载指令 CalNormal(&pData->MagPara.Mag_Bb[0], 3, &tmpModB); CalNormal(&tmpHwb[0], 3, &tmpModH); //计算卫星本体系下卸载标志 tmpk1=tmpConst->k1_dump; tmpk2=tmpConst->k2_dump; if(tmpModH>tmpk1) {pCtrl->IsDump=POSE_OK;} else if((tmpModH>tmpk2)&&(POSE_OK==pCtrl->IsDump)) {pCtrl->IsDump=POSE_OK;} else {pCtrl->IsDump=POSE_NO;} //计算磁卸载角 if ((tmpModB * tmpModH) > POSE_ZERO) { for(i=0;i<3;i++) { tmpJB[i] = tmpHwb[i]/(tmpModB * tmpModH); } Posedot(pData->MagPara.Mag_Bb,tmpJB,3, &tmpLamd); //结果为弧度 tmpang = POSE_ACOSF(tmpLamd); } else { tmpang = 0; } //计算磁力矩器控制器控制指令 if ((tmpang>tmpConst->MTAtt_dump)&&(tmpang< (180.0 *ANG2RADIAN - tmpConst->MTAtt_dump))&&(pCtrl->IsDump==POSE_OK)) { cross( pData->MagPara.Mag_Bb, tmpHwb , tempBXH ); for(i=0;i<3;i++) { if (tmpModB > POSE_ZERO) { pCtrl->MagCtrlResult[i] = - tmpConst->ku_dump * tempBXH[i] /tmpModB /tmpModB ; } else { pCtrl->MagCtrlResult[i]=0.0f; } } } else { memset(pCtrl->MagCtrlResult, 0.0, 3*sizeof(TYPE_CAL)); } } } void CtrlModPD2PID(void) { sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; sAttCtlPara_t *pCtrl =NULL; AttCtrlConst_t *tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; sAttDeterPara_t *pDeter =NULL; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; //tmpConst=(AttCtrlConst_t *)ATTCLT_DATA2_ADDR; if((NULL == tmpAtt) || (NULL == tmpConst)) {return;} TYPE_CAL tmpAng = 5.0f * ANG2RADIAN; TYPE_CAL tmpAngRat = 0.1f * ANG2RADIAN; pCtrl=&tmpAtt->sCtlPara; pDeter=&tmpAtt->sDeterPara; if ((0x55 == pDeter->CLPAttValid) && (POSE_ABSF(pDeter->CLPAttAng[0])CLPAttAng[1])CLPAttAng[2])CLPAttAngRat[0])CLPAttAngRat[1])CLPAttAngRat[2])PD2PIDCnt<60000) {pCtrl->PD2PIDCnt++;} if (20 <= pCtrl->PD2PIDCnt) { pCtrl->CtrlPD2PID = POSE_OK; } } else { pCtrl->PD2PIDCnt = 0; } if (POSE_OK == pCtrl->CtrlPD2PID) { WheelCalc_PID(); //pCtrl->AttCtrl_TypeTEST=2; } else { WheelCalc_PD(); //pCtrl->AttCtrl_TypeTEST=1; } } /************************************************ 说明:姿态控制算法,根据使用状态进行控制模式选择 输入: 控制模式标志 输出: ************************************************/ void ZKPosCtlAct(sAttDeterPara_t *pAttDet, sAttGuidLawPara_t *pAttGuid, sAttCtlPara_t *pAttCtrl) { sAttPriData *tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; sAttCtlPara_t *pCtrl =NULL; sAttModPara_t *pWMod =NULL; //tmpAtt=(sAttPriData *)ATTCLT_DATA1_ADDR; if(NULL == tmpAtt) {return;} pCtrl=&tmpAtt->sCtlPara; pWMod=&tmpAtt->sModePara; #ifdef MINMODULE_TYPE //初始化 memset(pCtrl->Mag_DeltBb, 0.0f, 3*sizeof(TYPE_CAL)); //计算飞轮角动量和三轴角动量 Whl_Momentum_Count(); switch (tmpAtt->sModePara.WorkMode) { case ATTMOD_RATEDMP: /*速率阻尼*/ MagDmpMomentCal(); break; case ATTMOD_MagTOSUN: //磁控对日 MagSunMomentCal(); break; default: break; } #else //初始化 ZKPosCtlOutInit(); //计算飞轮角动量和三轴角动量 Whl_Momentum_Count(); //pAttCtrl->AttCtrl_TypeTEST=0; switch (tmpAtt->sModePara.WorkMode) { case ATTMOD_BREAKPRE: /*星箭分离前*/ //pAttCtrl->AttCtrl_Type=0; break; case ATTMOD_NOCOLL: /*碰撞规避模式*/ if (pWMod->WModCnt1 >= 40) { WheelCalc_PD();} else { memset(pCtrl->WheelCtrlResult, 0.0f, 3*sizeof(TYPE_CAL)); memset(pCtrl->WheelCtrlResultPre, 0.0f, 3*sizeof(TYPE_CAL)); } //pAttCtrl->AttCtrl_Type=1; break; case ATTMOD_RATEDMP: /*速率阻尼*/ MagDmpMomentCal(); //pAttCtrl->AttCtrl_Type=2; break; //case ATTMOD_TOSUN: /*对日定向*/ case ATTMOD_MagTOSUN: //磁控对日 MagSunMomentCal(); break; case ATTMOD_WhlTOSUN: //轮控对日 WheelCalc_PD(); CtrlWheelReleaseProc(); //pAttCtrl->AttCtrl_Type=1; break; case ATTMOD_ONLTOEARTH: /*对地定向*/ WheelCalc_PD(); memset(pCtrl->MagCtrlResult, 0.0f, 3*sizeof(TYPE_CAL)); //pAttCtrl->AttCtrl_Type=1; break; case ATTMOD_WHEELTOEARTH: /*稳态对地*/ CtrlModPD2PID(); CtrlWheelReleaseProc(); break; case ATTMOD_ATTAJUSTPRE: /*轨控前调姿*/ WheelCalc_PD(); CtrlWheelReleaseProc(); //memset(pCtrl->MagCtrlResult, 0.0, 3*sizeof(TYPE_CAL)); break; case ATTMOD_ORBITCTL: /*轨道控制*/ CtrlModPD2PID(); CtrlWheelReleaseProc(); break; case ATTMOD_ATTAJUST: /*定向前调姿*/ WheelCalc_PD(); CtrlWheelReleaseProc(); //memset(pCtrl->MagCtrlResult, 0.0, 3*sizeof(TYPE_CAL)); break; case ATTMOD_ONLTOTAR: /*对目标定向*/ CtrlModPD2PID(); CtrlWheelReleaseProc(); break; case ATTMOD_UNCTL: /*无控模式*/ memset(pCtrl->WheelCtrlResult, 0.0f, 3*sizeof(TYPE_CAL)); memset(pCtrl->MagCtrlResult, 0.0f, 3*sizeof(TYPE_CAL)); break; default: break; } #endif }