1.lab02b相对lab02a将ctrl_run()函数开源,
2.控制器有三种状态:
if(ctrlState == CTRL_State_OnLine)
{
CTRL_Obj *obj = (CTRL_Obj *)handle;
// increment the current count
CTRL_incrCounter_current(handle);
// increment the speed count
CTRL_incrCounter_speed(handle);
if(EST_getState(obj->estHandle) >= EST_State_MotorIdentified)
{
// run the online controller
CTRL_runOnLine_User(handle,pAdcData,pPwmData);
}
else
{
// run the online controller
CTRL_runOnLine(handle,pAdcData,pPwmData);
}
}
else if(ctrlState == CTRL_State_OffLine)
{
// run the offline controller
CTRL_runOffLine(handle,halHandle,pAdcData,pPwmData);
}
else if(ctrlState == CTRL_State_Idle)
{
// set all pwm outputs to zero
pPwmData->Tabc.value[0] = _IQ(0.0);
pPwmData->Tabc.value[1] = _IQ(0.0);
pPwmData->Tabc.value[2] = _IQ(0.0);
}
idle:PWM输出置0;
offline:CTRL_runOffLine()函数进行offset计算(一阶滤波),和将PWM置0;
online:如果电机辨识完成,运行CTRL_runOnLine_User(handle,pAdcData,pPwmData);//FOC实现程序,将2a的代码开源
电机未辨识,运行CTRL_runOnLine(handle,pAdcData,pPwmData);电机进行R、L、RATED_FLUX是否是在这里进行,估算器EST代码是否开源:
就是实现电机参数辨识的算法,在CTRL_runOnLine()函数没有找到相关代码。
对比CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数和CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数并没有太大的区别,这是怎么实现的电机参数辨识算法?
3.FAST observer是FAST观测器 ,输出Flux、angle 、speed、torque.
估算器EST指的就是运行电机参数辨识的程序吗,
这两个是不同的,是吗?谢谢~
HeiHei:
EST就是运行电机参数辨识。
1.lab02b相对lab02a将ctrl_run()函数开源,
2.控制器有三种状态:
if(ctrlState == CTRL_State_OnLine)
{
CTRL_Obj *obj = (CTRL_Obj *)handle;
// increment the current count
CTRL_incrCounter_current(handle);
// increment the speed count
CTRL_incrCounter_speed(handle);
if(EST_getState(obj->estHandle) >= EST_State_MotorIdentified)
{
// run the online controller
CTRL_runOnLine_User(handle,pAdcData,pPwmData);
}
else
{
// run the online controller
CTRL_runOnLine(handle,pAdcData,pPwmData);
}
}
else if(ctrlState == CTRL_State_OffLine)
{
// run the offline controller
CTRL_runOffLine(handle,halHandle,pAdcData,pPwmData);
}
else if(ctrlState == CTRL_State_Idle)
{
// set all pwm outputs to zero
pPwmData->Tabc.value[0] = _IQ(0.0);
pPwmData->Tabc.value[1] = _IQ(0.0);
pPwmData->Tabc.value[2] = _IQ(0.0);
}
idle:PWM输出置0;
offline:CTRL_runOffLine()函数进行offset计算(一阶滤波),和将PWM置0;
online:如果电机辨识完成,运行CTRL_runOnLine_User(handle,pAdcData,pPwmData);//FOC实现程序,将2a的代码开源
电机未辨识,运行CTRL_runOnLine(handle,pAdcData,pPwmData);电机进行R、L、RATED_FLUX是否是在这里进行,估算器EST代码是否开源:
就是实现电机参数辨识的算法,在CTRL_runOnLine()函数没有找到相关代码。
对比CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数和CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数并没有太大的区别,这是怎么实现的电机参数辨识算法?
3.FAST observer是FAST观测器 ,输出Flux、angle 、speed、torque.
估算器EST指的就是运行电机参数辨识的程序吗,
这两个是不同的,是吗?谢谢~
ming chen3:
回复 HeiHei:
文档中写到:
when the motor is being identified CTRL_runOnLine is executed from ROM. After the motor is identified, CTRL_runOnLine_User is run from user RAM. CTRL_runOnLine_User is an inlined function that is located in ctrl.h. It contains the entire FOC implementation with calls to the FAST observer for rotor flux angle values.
电机未辨识,运行CTRL_runOnLine(handle,pAdcData,pPwmData);电机进行参数辨识的估算器算法在这里执行完成。
电机识别完成,运行CTRL_runOnLine_User(handle,pAdcData,pPwmData);//调用FAST观测器的电角度实现完整的FOC控制。
这两个函数实现不同的功能,对比CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数和CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数并没有太大的区别,请详细分析下电机参数辨识在CTRL_runOnLine函数是如何实现的?估算器部分程序不开源具体是在哪里调用的,谢谢
附上CTRL_runOnLine(handle,pAdcData,pPwmData)函数:
//! \brief Runs the online controller//! \param[in] handle The controller (CTRL) handle//! \param[in] pAdcData The pointer to the ADC data//! \param[out] pPwmData The pointer to the PWM datainline void CTRL_runOnLine(CTRL_Handle handle, const HAL_AdcData_t *pAdcData,HAL_PwmData_t *pPwmData){ CTRL_Obj *obj = (CTRL_Obj *)handle;
_iq angle_pu;
MATH_vec2 phasor;
// run Clarke transform on current CLARKE_run(obj->clarkeHandle_I,&pAdcData->I,CTRL_getIab_in_addr(handle));
// run Clarke transform on voltage CLARKE_run(obj->clarkeHandle_V,&pAdcData->V,CTRL_getVab_in_addr(handle));
// run the estimator EST_run(obj->estHandle,CTRL_getIab_in_addr(handle),CTRL_getVab_in_addr(handle), pAdcData->dcBus,TRAJ_getIntValue(obj->trajHandle_spd));
// generate the motor electrical angle angle_pu = EST_getAngle_pu(obj->estHandle);
// compute the sin/cos phasor CTRL_computePhasor(angle_pu,&phasor);
// set the phasor in the Park transform PARK_setPhasor(obj->parkHandle,&phasor);
// run the Park transform PARK_run(obj->parkHandle,CTRL_getIab_in_addr(handle),CTRL_getIdq_in_addr(handle));
// when appropriate, run the PID speed controller if(EST_doSpeedCtrl(obj->estHandle)) { if(CTRL_doSpeedCtrl(handle)) { _iq refValue = TRAJ_getIntValue(obj->trajHandle_spd); _iq fbackValue = EST_getFm_pu(obj->estHandle); _iq outMax = TRAJ_getIntValue(obj->trajHandle_spdMax); _iq outMin = -outMax;
// reset the speed count CTRL_resetCounter_speed(handle);
PID_setMinMax(obj->pidHandle_spd,outMin,outMax);
PID_run_spd(obj->pidHandle_spd,refValue,fbackValue,CTRL_getSpd_out_addr(handle)); } } else { // zero the speed command CTRL_setSpd_out_pu(handle,_IQ(0.0));
// reset the integrator PID_setUi(obj->pidHandle_spd,_IQ(0.0)); }
// when appropriate, run the PID Id and Iq controllers if(CTRL_doCurrentCtrl(handle) && EST_doCurrentCtrl(obj->estHandle)) { _iq Kp_Id = CTRL_getKp(handle,CTRL_Type_PID_Id); _iq Kp_Iq = CTRL_getKp(handle,CTRL_Type_PID_Iq); _iq refValue; _iq fbackValue; _iq outMin,outMax; _iq maxVsMag = CTRL_getMaxVsMag_pu(handle);
// reset the current count CTRL_resetCounter_current(handle);
// *********************************** // configure and run the Id controller
// compute the Kp gain // Scale Kp instead of output to prevent saturation issues if(CTRL_getFlag_enableDcBusComp(handle)) { Kp_Id = _IQmpy(Kp_Id,EST_getOneOverDcBus_pu(obj->estHandle)); }
PID_setKp(obj->pidHandle_Id,Kp_Id);
// compute the reference value refValue = TRAJ_getIntValue(obj->trajHandle_Id) + CTRL_getId_ref_pu(handle);
// update the Id reference value EST_updateId_ref_pu(obj->estHandle,&refValue);
// get the feedback value fbackValue = CTRL_getId_in_pu(handle);
// set minimum and maximum for Id controller output outMax = maxVsMag; outMin = -outMax;
// set the minimum and maximum values PID_setMinMax(obj->pidHandle_Id,outMin,outMax);
// run the Id PID controller PID_run(obj->pidHandle_Id,refValue,fbackValue,CTRL_getVd_out_addr(handle));
// set the Id reference value in the estimator EST_setId_ref_pu(obj->estHandle,refValue);
// *********************************** // configure and run the Iq controller
// compute the Kp gain // Scale Kp instead of output to prevent saturation issues if(CTRL_getFlag_enableDcBusComp(handle)) { Kp_Iq = _IQmpy(Kp_Iq,EST_getOneOverDcBus_pu(obj->estHandle)); }
PID_setKp(obj->pidHandle_Iq,Kp_Iq);
// get the reference value if(CTRL_getFlag_enableSpeedCtrl(handle)) { if(!CTRL_useZeroIq_ref(handle)) { refValue = CTRL_getSpd_out_pu(handle); } else { refValue = _IQ(0.0); } } else { // get the Iq reference value refValue = CTRL_getIq_ref_pu(handle); }
// get the feedback value fbackValue = CTRL_getIq_in_pu(handle);
// generate the Iq PID output limits without square root outMax = maxVsMag – _IQabs(CTRL_getVd_out_pu(handle)); outMin = -outMax;
// set the minimum and maximum values PID_setMinMax(obj->pidHandle_Iq,outMin,outMax);
// run the Iq PID controller PID_run(obj->pidHandle_Iq,refValue,fbackValue,CTRL_getVq_out_addr(handle));
// set the Iq reference value in the estimator EST_setIq_ref_pu(obj->estHandle,refValue); }
// set the phasor in the inverse Park transform IPARK_setPhasor(obj->iparkHandle,&phasor);
// run the inverse Park module IPARK_run(obj->iparkHandle,CTRL_getVdq_out_addr(handle),CTRL_getVab_out_addr(handle));
// run the space Vector Generator (SVGEN) module SVGEN_run(obj->svgenHandle,CTRL_getVab_out_addr(handle),&(pPwmData->Tabc));
return;} // end of CTRL_runOnLine() function
附上CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数://! \brief Runs the online user controller//! \details An implementation of the field oriented control. The online user controller//! is executed in user's memory i.e. RAM/FLASH and can be changed in any way//! suited to the user.//! \param[in] handle The controller (CTRL) handle//! \param[in] pAdcData The pointer to the ADC data//! \param[out] pPwmData The pointer to the PWM datainline void CTRL_runOnLine_User(CTRL_Handle handle, const HAL_AdcData_t *pAdcData,HAL_PwmData_t *pPwmData){ CTRL_Obj *obj = (CTRL_Obj *)handle;
_iq angle_pu;
MATH_vec2 phasor;
// run Clarke transform on current CLARKE_run(obj->clarkeHandle_I,&pAdcData->I,CTRL_getIab_in_addr(handle));
// run Clarke transform on voltage CLARKE_run(obj->clarkeHandle_V,&pAdcData->V,CTRL_getVab_in_addr(handle));
// run the estimator EST_run(obj->estHandle,CTRL_getIab_in_addr(handle),CTRL_getVab_in_addr(handle), pAdcData->dcBus,TRAJ_getIntValue(obj->trajHandle_spd));
// generate the motor electrical angle angle_pu = EST_getAngle_pu(obj->estHandle);
// compute the sin/cos phasor CTRL_computePhasor(angle_pu,&phasor);
// set the phasor in the Park transform PARK_setPhasor(obj->parkHandle,&phasor);
// run the Park transform PARK_run(obj->parkHandle,CTRL_getIab_in_addr(handle),CTRL_getIdq_in_addr(handle));
// when appropriate, run the PID speed controller if(CTRL_doSpeedCtrl(handle)) { _iq refValue = TRAJ_getIntValue(obj->trajHandle_spd); _iq fbackValue = EST_getFm_pu(obj->estHandle); _iq outMax = TRAJ_getIntValue(obj->trajHandle_spdMax); _iq outMin = -outMax;
// reset the speed count CTRL_resetCounter_speed(handle);
PID_setMinMax(obj->pidHandle_spd,outMin,outMax);
PID_run_spd(obj->pidHandle_spd,refValue,fbackValue,CTRL_getSpd_out_addr(handle)); }
// when appropriate, run the PID Id and Iq controllers if(CTRL_doCurrentCtrl(handle)) { _iq Kp_Id = CTRL_getKp(handle,CTRL_Type_PID_Id); _iq Kp_Iq = CTRL_getKp(handle,CTRL_Type_PID_Iq); _iq refValue; _iq fbackValue; _iq outMin,outMax;
// read max voltage vector to set proper limits to current controllers _iq maxVsMag = CTRL_getMaxVsMag_pu(handle);
// reset the current count CTRL_resetCounter_current(handle);
// *********************************** // configure and run the Id controller
// compute the Kp gain // Scale Kp instead of output to prevent saturation issues if(CTRL_getFlag_enableDcBusComp(handle)) { Kp_Id = _IQmpy(Kp_Id,EST_getOneOverDcBus_pu(obj->estHandle)); }
PID_setKp(obj->pidHandle_Id,Kp_Id);
// compute the reference value refValue = TRAJ_getIntValue(obj->trajHandle_Id) + CTRL_getId_ref_pu(handle);
// update the Id reference value EST_updateId_ref_pu(obj->estHandle,&refValue);
// get the feedback value fbackValue = CTRL_getId_in_pu(handle);
// set minimum and maximum for Id controller output outMax = maxVsMag; outMin = -outMax;
// set the minimum and maximum values PID_setMinMax(obj->pidHandle_Id,outMin,outMax);
// run the Id PID controller PID_run(obj->pidHandle_Id,refValue,fbackValue,CTRL_getVd_out_addr(handle));
// *********************************** // configure and run the Iq controller
// compute the Kp gain // Scale Kp instead of output to prevent saturation issues if(CTRL_getFlag_enableDcBusComp(handle)) { Kp_Iq = _IQmpy(Kp_Iq,EST_getOneOverDcBus_pu(obj->estHandle)); }
PID_setKp(obj->pidHandle_Iq,Kp_Iq);
// get the reference value if(CTRL_getFlag_enableSpeedCtrl(handle)) { refValue = CTRL_getSpd_out_pu(handle); } else { // get the Iq reference value refValue = CTRL_getIq_ref_pu(handle); }
// get the feedback value fbackValue = CTRL_getIq_in_pu(handle);
// set minimum and maximum for Id controller output outMax = _IQsqrt(_IQmpy(maxVsMag,maxVsMag) – _IQmpy(CTRL_getVd_out_pu(handle),CTRL_getVd_out_pu(handle))); outMin = -outMax;
// set the minimum and maximum values PID_setMinMax(obj->pidHandle_Iq,outMin,outMax);
// run the Iq PID controller PID_run(obj->pidHandle_Iq,refValue,fbackValue,CTRL_getVq_out_addr(handle)); }
{ _iq angleComp_pu;
// compensate angle delay angleComp_pu = CTRL_angleDelayComp(handle, angle_pu);
// compute the sin/cos phasor CTRL_computePhasor(angleComp_pu,&phasor); }
// set the phasor in the inverse Park transform IPARK_setPhasor(obj->iparkHandle,&phasor);
// run the inverse Park module IPARK_run(obj->iparkHandle,CTRL_getVdq_out_addr(handle),CTRL_getVab_out_addr(handle));
// run the space Vector Generator (SVGEN) module SVGEN_run(obj->svgenHandle,CTRL_getVab_out_addr(handle),&(pPwmData->Tabc));
return;} // end of CTRL_runOnLine_User() function
1.lab02b相对lab02a将ctrl_run()函数开源,
2.控制器有三种状态:
if(ctrlState == CTRL_State_OnLine)
{
CTRL_Obj *obj = (CTRL_Obj *)handle;
// increment the current count
CTRL_incrCounter_current(handle);
// increment the speed count
CTRL_incrCounter_speed(handle);
if(EST_getState(obj->estHandle) >= EST_State_MotorIdentified)
{
// run the online controller
CTRL_runOnLine_User(handle,pAdcData,pPwmData);
}
else
{
// run the online controller
CTRL_runOnLine(handle,pAdcData,pPwmData);
}
}
else if(ctrlState == CTRL_State_OffLine)
{
// run the offline controller
CTRL_runOffLine(handle,halHandle,pAdcData,pPwmData);
}
else if(ctrlState == CTRL_State_Idle)
{
// set all pwm outputs to zero
pPwmData->Tabc.value[0] = _IQ(0.0);
pPwmData->Tabc.value[1] = _IQ(0.0);
pPwmData->Tabc.value[2] = _IQ(0.0);
}
idle:PWM输出置0;
offline:CTRL_runOffLine()函数进行offset计算(一阶滤波),和将PWM置0;
online:如果电机辨识完成,运行CTRL_runOnLine_User(handle,pAdcData,pPwmData);//FOC实现程序,将2a的代码开源
电机未辨识,运行CTRL_runOnLine(handle,pAdcData,pPwmData);电机进行R、L、RATED_FLUX是否是在这里进行,估算器EST代码是否开源:
就是实现电机参数辨识的算法,在CTRL_runOnLine()函数没有找到相关代码。
对比CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数和CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数并没有太大的区别,这是怎么实现的电机参数辨识算法?
3.FAST observer是FAST观测器 ,输出Flux、angle 、speed、torque.
估算器EST指的就是运行电机参数辨识的程序吗,
这两个是不同的,是吗?谢谢~
ming chen3:
回复 ming chen3:
CTRL_runOnLine函数是如何实现参数辨识的?谢谢~
1.lab02b相对lab02a将ctrl_run()函数开源,
2.控制器有三种状态:
if(ctrlState == CTRL_State_OnLine)
{
CTRL_Obj *obj = (CTRL_Obj *)handle;
// increment the current count
CTRL_incrCounter_current(handle);
// increment the speed count
CTRL_incrCounter_speed(handle);
if(EST_getState(obj->estHandle) >= EST_State_MotorIdentified)
{
// run the online controller
CTRL_runOnLine_User(handle,pAdcData,pPwmData);
}
else
{
// run the online controller
CTRL_runOnLine(handle,pAdcData,pPwmData);
}
}
else if(ctrlState == CTRL_State_OffLine)
{
// run the offline controller
CTRL_runOffLine(handle,halHandle,pAdcData,pPwmData);
}
else if(ctrlState == CTRL_State_Idle)
{
// set all pwm outputs to zero
pPwmData->Tabc.value[0] = _IQ(0.0);
pPwmData->Tabc.value[1] = _IQ(0.0);
pPwmData->Tabc.value[2] = _IQ(0.0);
}
idle:PWM输出置0;
offline:CTRL_runOffLine()函数进行offset计算(一阶滤波),和将PWM置0;
online:如果电机辨识完成,运行CTRL_runOnLine_User(handle,pAdcData,pPwmData);//FOC实现程序,将2a的代码开源
电机未辨识,运行CTRL_runOnLine(handle,pAdcData,pPwmData);电机进行R、L、RATED_FLUX是否是在这里进行,估算器EST代码是否开源:
就是实现电机参数辨识的算法,在CTRL_runOnLine()函数没有找到相关代码。
对比CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数和CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数并没有太大的区别,这是怎么实现的电机参数辨识算法?
3.FAST observer是FAST观测器 ,输出Flux、angle 、speed、torque.
估算器EST指的就是运行电机参数辨识的程序吗,
这两个是不同的,是吗?谢谢~
HeiHei:
回复 ming chen3:
参数辨识部分的程序是固化在ROM里的 在程序中调用即可,具体的原理老外没有公开,只是提供了接口参数。另外你可以看一下motorware中相关的文档:
InstaSPIN-FOC™ and InstaSPIN-MOTION™ User's Guide
1.lab02b相对lab02a将ctrl_run()函数开源,
2.控制器有三种状态:
if(ctrlState == CTRL_State_OnLine)
{
CTRL_Obj *obj = (CTRL_Obj *)handle;
// increment the current count
CTRL_incrCounter_current(handle);
// increment the speed count
CTRL_incrCounter_speed(handle);
if(EST_getState(obj->estHandle) >= EST_State_MotorIdentified)
{
// run the online controller
CTRL_runOnLine_User(handle,pAdcData,pPwmData);
}
else
{
// run the online controller
CTRL_runOnLine(handle,pAdcData,pPwmData);
}
}
else if(ctrlState == CTRL_State_OffLine)
{
// run the offline controller
CTRL_runOffLine(handle,halHandle,pAdcData,pPwmData);
}
else if(ctrlState == CTRL_State_Idle)
{
// set all pwm outputs to zero
pPwmData->Tabc.value[0] = _IQ(0.0);
pPwmData->Tabc.value[1] = _IQ(0.0);
pPwmData->Tabc.value[2] = _IQ(0.0);
}
idle:PWM输出置0;
offline:CTRL_runOffLine()函数进行offset计算(一阶滤波),和将PWM置0;
online:如果电机辨识完成,运行CTRL_runOnLine_User(handle,pAdcData,pPwmData);//FOC实现程序,将2a的代码开源
电机未辨识,运行CTRL_runOnLine(handle,pAdcData,pPwmData);电机进行R、L、RATED_FLUX是否是在这里进行,估算器EST代码是否开源:
就是实现电机参数辨识的算法,在CTRL_runOnLine()函数没有找到相关代码。
对比CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数和CTRL_runOnLine_User(handle,pAdcData,pPwmData)函数并没有太大的区别,这是怎么实现的电机参数辨识算法?
3.FAST observer是FAST观测器 ,输出Flux、angle 、speed、torque.
估算器EST指的就是运行电机参数辨识的程序吗,
这两个是不同的,是吗?谢谢~
ming chen3:
回复 HeiHei:
非常感谢您的回答~
我有看过User's Guide的chapter 6 他具体的参数辨识策略,我也都能明白。只是这两个函数完全实现不同的功能,但对比这两个函数没有发现太大的区别。
电机未辨识,运行CTRL_runOnLine(handle,pAdcData,pPwmData);电机进行参数辨识的估算器算法在这里执行完成。
电机识别完成,运行CTRL_runOnLine_User(handle,pAdcData,pPwmData);//调用FAST观测器的电角度实现完整的FOC控制。
有如下几处差别:
1.TI有没有关于ROM中的算法和用户存储区代码的相关说明,和具体调用策略。谢谢~