industry/foc/foc_align: add support for sensor index search
This commit is contained in:
parent
15b66aa128
commit
54c0b9a9d8
@ -46,7 +46,8 @@ enum foc_routine_run_e
|
|||||||
struct foc_routine_in_b16_s
|
struct foc_routine_in_b16_s
|
||||||
{
|
{
|
||||||
FAR struct foc_state_b16_s *foc_state; /* FOC controller state */
|
FAR struct foc_state_b16_s *foc_state; /* FOC controller state */
|
||||||
b16_t angle; /* Angle now */
|
b16_t angle; /* Angle electrical now */
|
||||||
|
b16_t angle_m; /* Angle mechanical now */
|
||||||
b16_t vel; /* Velocity now */
|
b16_t vel; /* Velocity now */
|
||||||
b16_t vbus; /* VBUS now */
|
b16_t vbus; /* VBUS now */
|
||||||
};
|
};
|
||||||
|
@ -46,7 +46,8 @@ enum foc_routine_run_e
|
|||||||
struct foc_routine_in_f32_s
|
struct foc_routine_in_f32_s
|
||||||
{
|
{
|
||||||
FAR struct foc_state_f32_s *foc_state; /* FOC controller state */
|
FAR struct foc_state_f32_s *foc_state; /* FOC controller state */
|
||||||
float angle; /* Angle now */
|
float angle; /* Angle electrical now */
|
||||||
|
float angle_m; /* Angle mechanical now */
|
||||||
float vel; /* Velocity now */
|
float vel; /* Velocity now */
|
||||||
float vbus; /* VBUS now */
|
float vbus; /* VBUS now */
|
||||||
};
|
};
|
||||||
|
@ -121,6 +121,16 @@ config INDUSTRY_FOC_ALIGN
|
|||||||
---help---
|
---help---
|
||||||
Enable support for angle sensor alignment routine (zero offset + direction)
|
Enable support for angle sensor alignment routine (zero offset + direction)
|
||||||
|
|
||||||
|
if INDUSTRY_FOC_ALIGN
|
||||||
|
|
||||||
|
config INDUSTRY_FOC_ALIGN_INDEX
|
||||||
|
bool "FOC alignment index search support"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enable support for sensor alignment index search
|
||||||
|
|
||||||
|
endif # INDUSTRY_FOC_ALIGN
|
||||||
|
|
||||||
config INDUSTRY_FOC_IDENT
|
config INDUSTRY_FOC_IDENT
|
||||||
bool "FOC motor identification routine"
|
bool "FOC motor identification routine"
|
||||||
default n
|
default n
|
||||||
|
@ -56,6 +56,12 @@
|
|||||||
|
|
||||||
#define IDLE_STEPS (500)
|
#define IDLE_STEPS (500)
|
||||||
|
|
||||||
|
/* Index alignment */
|
||||||
|
|
||||||
|
#define ALIGN_INDEX_ANGLE_SIGN (-b16muli(b16PI, 2))
|
||||||
|
#define ALIGN_INDEX_ANGLE_STEP (ftob16(0.001f))
|
||||||
|
#define ALIGN_INDEX_ANGLE_NOZERO (ftob16(0.1f))
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data Types
|
* Private Data Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -65,6 +71,9 @@
|
|||||||
enum foc_align_run_stage_e
|
enum foc_align_run_stage_e
|
||||||
{
|
{
|
||||||
FOC_ALIGN_RUN_INIT,
|
FOC_ALIGN_RUN_INIT,
|
||||||
|
#ifdef CONFIG_INDUSTRY_FOC_ALIGN_INDEX
|
||||||
|
FOC_ALIGN_RUN_INDEX,
|
||||||
|
#endif
|
||||||
FOC_ALIGN_RUN_OFFSET,
|
FOC_ALIGN_RUN_OFFSET,
|
||||||
FOC_ALIGN_RUN_DIR,
|
FOC_ALIGN_RUN_DIR,
|
||||||
FOC_ALIGN_RUN_IDLE,
|
FOC_ALIGN_RUN_IDLE,
|
||||||
@ -80,6 +89,10 @@ struct foc_align_b16_s
|
|||||||
int cntr;
|
int cntr;
|
||||||
int stage;
|
int stage;
|
||||||
int dir_step;
|
int dir_step;
|
||||||
|
#ifdef CONFIG_INDUSTRY_FOC_ALIGN_INDEX
|
||||||
|
int index_step;
|
||||||
|
b16_t index_angle;
|
||||||
|
#endif
|
||||||
b16_t dir_angle;
|
b16_t dir_angle;
|
||||||
b16_t angle_last;
|
b16_t angle_last;
|
||||||
b16_t angle_now;
|
b16_t angle_now;
|
||||||
@ -116,6 +129,148 @@ struct foc_routine_ops_b16_s g_foc_routine_align_b16 =
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_INDUSTRY_FOC_ALIGN_INDEX
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: foc_align_index_run_b16
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Run index alignment routine
|
||||||
|
*
|
||||||
|
* Input Parameter:
|
||||||
|
* align - pointer to FOC align routine
|
||||||
|
* in - pointer to FOC routine input data
|
||||||
|
* out - pointer to FOC routine output data
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int foc_align_index_run_b16(FAR struct foc_align_b16_s *align,
|
||||||
|
FAR struct foc_routine_in_b16_s *in,
|
||||||
|
FAR struct foc_routine_out_b16_s *out)
|
||||||
|
{
|
||||||
|
static b16_t dir = DIR_CW_B16;
|
||||||
|
b16_t sign = 0;
|
||||||
|
int ret = FOC_ROUTINE_RUN_NOTDONE;
|
||||||
|
|
||||||
|
/* Get mechanical angles */
|
||||||
|
|
||||||
|
align->angle_last = align->angle_now;
|
||||||
|
align->angle_now = in->angle_m;
|
||||||
|
|
||||||
|
/* Normalize angle to <-M_PI, M_PI> range */
|
||||||
|
|
||||||
|
align->angle_now = align->angle_now - b16PI;
|
||||||
|
angle_norm_2pi_b16(&align->angle_now, -b16PI, b16PI);
|
||||||
|
|
||||||
|
/* The product of the previous angle with an angle now gives us
|
||||||
|
* information about the encoder overflow.
|
||||||
|
* This procedure assumes that the encoder index signal resets the
|
||||||
|
* encoder value to zero.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sign = b16mulb16(align->angle_now, align->angle_last);
|
||||||
|
|
||||||
|
/* Move the motor shaft to approach index signal from both direction.
|
||||||
|
* After that, the encoder zero should be aligned with the encoder index.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (align->index_step == 0)
|
||||||
|
{
|
||||||
|
/* Move the motor shaft away from zero */
|
||||||
|
|
||||||
|
align->index_angle += b16mulb16(dir, ALIGN_INDEX_ANGLE_STEP);
|
||||||
|
|
||||||
|
if (align->angle_now < ALIGN_INDEX_ANGLE_NOZERO &&
|
||||||
|
align->angle_now > -ALIGN_INDEX_ANGLE_NOZERO)
|
||||||
|
{
|
||||||
|
align->index_step += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (align->index_step == 1)
|
||||||
|
{
|
||||||
|
/* Move the motor shaft to zero in positive direction */
|
||||||
|
|
||||||
|
align->index_angle += b16mulb16(dir, ALIGN_INDEX_ANGLE_STEP);
|
||||||
|
|
||||||
|
if (sign < 0 && sign < ALIGN_INDEX_ANGLE_SIGN)
|
||||||
|
{
|
||||||
|
dir = b16mulb16(DIR_CCW_B16, dir);
|
||||||
|
align->index_step += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (align->index_step == 2)
|
||||||
|
{
|
||||||
|
/* Move the motor shaft away from zero */
|
||||||
|
|
||||||
|
align->index_angle += b16mulb16(dir, ALIGN_INDEX_ANGLE_STEP);
|
||||||
|
|
||||||
|
if (align->angle_now < ALIGN_INDEX_ANGLE_NOZERO &&
|
||||||
|
align->angle_now > -ALIGN_INDEX_ANGLE_NOZERO)
|
||||||
|
{
|
||||||
|
align->index_step += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (align->index_step == 3)
|
||||||
|
{
|
||||||
|
/* Move the motor shaft to zero in negative direction */
|
||||||
|
|
||||||
|
align->index_angle += b16mulb16(dir, ALIGN_INDEX_ANGLE_STEP);
|
||||||
|
|
||||||
|
if (sign < 0 && sign < ALIGN_INDEX_ANGLE_SIGN)
|
||||||
|
{
|
||||||
|
dir = b16mulb16(DIR_CCW_B16, dir);
|
||||||
|
align->index_step += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (align->index_step == 4)
|
||||||
|
{
|
||||||
|
/* Done */
|
||||||
|
|
||||||
|
ret = FOC_ROUTINE_RUN_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get output */
|
||||||
|
|
||||||
|
if (ret == FOC_ROUTINE_RUN_DONE)
|
||||||
|
{
|
||||||
|
/* Force IDLE mode */
|
||||||
|
|
||||||
|
out->dq_ref.q = 0;
|
||||||
|
out->dq_ref.d = 0;
|
||||||
|
out->vdq_comp.q = 0;
|
||||||
|
out->vdq_comp.d = 0;
|
||||||
|
out->angle = 0;
|
||||||
|
out->foc_mode = FOC_HANDLER_MODE_IDLE;
|
||||||
|
|
||||||
|
/* Reset data */
|
||||||
|
|
||||||
|
align->angle_last = 0;
|
||||||
|
align->angle_now = 0;
|
||||||
|
align->cntr = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Force DQ voltage vector */
|
||||||
|
|
||||||
|
out->dq_ref.q = align->cfg.volt;
|
||||||
|
out->dq_ref.d = 0;
|
||||||
|
out->vdq_comp.q = 0;
|
||||||
|
out->vdq_comp.d = 0;
|
||||||
|
out->angle = align->index_angle;
|
||||||
|
out->foc_mode = FOC_HANDLER_MODE_VOLTAGE;
|
||||||
|
|
||||||
|
/* Increase counter */
|
||||||
|
|
||||||
|
align->cntr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: foc_align_offset_run_b16
|
* Name: foc_align_offset_run_b16
|
||||||
*
|
*
|
||||||
@ -711,6 +866,29 @@ int foc_routine_align_run_b16(FAR foc_routine_b16_t *r,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_INDUSTRY_FOC_ALIGN_INDEX
|
||||||
|
case FOC_ALIGN_RUN_INDEX:
|
||||||
|
{
|
||||||
|
/* Align zero procedure */
|
||||||
|
|
||||||
|
ret = foc_align_index_run_b16(a, in, out);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == FOC_ROUTINE_RUN_DONE)
|
||||||
|
{
|
||||||
|
FOCLIBLOG("ALIGN INDEX done!\n");
|
||||||
|
|
||||||
|
a->stage += 1;
|
||||||
|
ret = FOC_ROUTINE_RUN_NOTDONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case FOC_ALIGN_RUN_OFFSET:
|
case FOC_ALIGN_RUN_OFFSET:
|
||||||
{
|
{
|
||||||
/* Align zero procedure */
|
/* Align zero procedure */
|
||||||
|
@ -56,6 +56,12 @@
|
|||||||
|
|
||||||
#define IDLE_STEPS (500)
|
#define IDLE_STEPS (500)
|
||||||
|
|
||||||
|
/* Index alignment */
|
||||||
|
|
||||||
|
#define ALIGN_INDEX_ANGLE_SIGN (-2.0f*M_PI)
|
||||||
|
#define ALIGN_INDEX_ANGLE_STEP (0.001f)
|
||||||
|
#define ALIGN_INDEX_ANGLE_NOZERO (0.1f)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data Types
|
* Private Data Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -65,6 +71,9 @@
|
|||||||
enum foc_align_run_stage_e
|
enum foc_align_run_stage_e
|
||||||
{
|
{
|
||||||
FOC_ALIGN_RUN_INIT,
|
FOC_ALIGN_RUN_INIT,
|
||||||
|
#ifdef CONFIG_INDUSTRY_FOC_ALIGN_INDEX
|
||||||
|
FOC_ALIGN_RUN_INDEX,
|
||||||
|
#endif
|
||||||
FOC_ALIGN_RUN_OFFSET,
|
FOC_ALIGN_RUN_OFFSET,
|
||||||
FOC_ALIGN_RUN_DIR,
|
FOC_ALIGN_RUN_DIR,
|
||||||
FOC_ALIGN_RUN_IDLE,
|
FOC_ALIGN_RUN_IDLE,
|
||||||
@ -80,6 +89,10 @@ struct foc_align_f32_s
|
|||||||
int cntr;
|
int cntr;
|
||||||
int stage;
|
int stage;
|
||||||
int dir_step;
|
int dir_step;
|
||||||
|
#ifdef CONFIG_INDUSTRY_FOC_ALIGN_INDEX
|
||||||
|
int index_step;
|
||||||
|
float index_angle;
|
||||||
|
#endif
|
||||||
float dir_angle;
|
float dir_angle;
|
||||||
float angle_last;
|
float angle_last;
|
||||||
float angle_now;
|
float angle_now;
|
||||||
@ -116,6 +129,148 @@ struct foc_routine_ops_f32_s g_foc_routine_align_f32 =
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_INDUSTRY_FOC_ALIGN_INDEX
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: foc_align_index_run_f32
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Run index alignment routine
|
||||||
|
*
|
||||||
|
* Input Parameter:
|
||||||
|
* align - pointer to FOC align routine
|
||||||
|
* in - pointer to FOC routine input data
|
||||||
|
* out - pointer to FOC routine output data
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int foc_align_index_run_f32(FAR struct foc_align_f32_s *align,
|
||||||
|
FAR struct foc_routine_in_f32_s *in,
|
||||||
|
FAR struct foc_routine_out_f32_s *out)
|
||||||
|
{
|
||||||
|
static float dir = DIR_CW;
|
||||||
|
float sign = 0.0f;
|
||||||
|
int ret = FOC_ROUTINE_RUN_NOTDONE;
|
||||||
|
|
||||||
|
/* Get mechanical angles */
|
||||||
|
|
||||||
|
align->angle_last = align->angle_now;
|
||||||
|
align->angle_now = in->angle_m;
|
||||||
|
|
||||||
|
/* Normalize angle to <-M_PI, M_PI> range */
|
||||||
|
|
||||||
|
align->angle_now = align->angle_now - M_PI;
|
||||||
|
angle_norm_2pi(&align->angle_now, -M_PI, M_PI);
|
||||||
|
|
||||||
|
/* The product of the previous angle with an angle now gives us
|
||||||
|
* information about the encoder overflow.
|
||||||
|
* This procedure assumes that the encoder index signal resets the
|
||||||
|
* encoder value to zero.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sign = align->angle_now * align->angle_last;
|
||||||
|
|
||||||
|
/* Move the motor shaft to approach index signal from both direction.
|
||||||
|
* After that, the encoder zero should be aligned with the encoder index.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (align->index_step == 0)
|
||||||
|
{
|
||||||
|
/* Move the motor shaft away from zero */
|
||||||
|
|
||||||
|
align->index_angle += dir * ALIGN_INDEX_ANGLE_STEP;
|
||||||
|
|
||||||
|
if (align->angle_now < ALIGN_INDEX_ANGLE_NOZERO &&
|
||||||
|
align->angle_now > -ALIGN_INDEX_ANGLE_NOZERO)
|
||||||
|
{
|
||||||
|
align->index_step += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (align->index_step == 1)
|
||||||
|
{
|
||||||
|
/* Move the motor shaft to zero in positive direction */
|
||||||
|
|
||||||
|
align->index_angle += dir * ALIGN_INDEX_ANGLE_STEP;
|
||||||
|
|
||||||
|
if (sign < 0.0f && sign < ALIGN_INDEX_ANGLE_SIGN)
|
||||||
|
{
|
||||||
|
dir = DIR_CCW * dir;
|
||||||
|
align->index_step += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (align->index_step == 2)
|
||||||
|
{
|
||||||
|
/* Move the motor shaft away from zero */
|
||||||
|
|
||||||
|
align->index_angle += dir * ALIGN_INDEX_ANGLE_STEP;
|
||||||
|
|
||||||
|
if (align->angle_now < ALIGN_INDEX_ANGLE_NOZERO &&
|
||||||
|
align->angle_now > -ALIGN_INDEX_ANGLE_NOZERO)
|
||||||
|
{
|
||||||
|
align->index_step += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (align->index_step == 3)
|
||||||
|
{
|
||||||
|
/* Move the motor shaft to zero in negative direction */
|
||||||
|
|
||||||
|
align->index_angle += dir * ALIGN_INDEX_ANGLE_STEP;
|
||||||
|
|
||||||
|
if (sign < 0.0f && sign < ALIGN_INDEX_ANGLE_SIGN)
|
||||||
|
{
|
||||||
|
dir = DIR_CCW * dir;
|
||||||
|
align->index_step += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (align->index_step == 4)
|
||||||
|
{
|
||||||
|
/* Done */
|
||||||
|
|
||||||
|
ret = FOC_ROUTINE_RUN_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get output */
|
||||||
|
|
||||||
|
if (ret == FOC_ROUTINE_RUN_DONE)
|
||||||
|
{
|
||||||
|
/* Force IDLE mode */
|
||||||
|
|
||||||
|
out->dq_ref.q = 0.0f;
|
||||||
|
out->dq_ref.d = 0.0f;
|
||||||
|
out->vdq_comp.q = 0.0f;
|
||||||
|
out->vdq_comp.d = 0.0f;
|
||||||
|
out->angle = 0.0f;
|
||||||
|
out->foc_mode = FOC_HANDLER_MODE_IDLE;
|
||||||
|
|
||||||
|
/* Reset data */
|
||||||
|
|
||||||
|
align->angle_last = 0.0f;
|
||||||
|
align->angle_now = 0.0f;
|
||||||
|
align->cntr = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Force DQ voltage vector */
|
||||||
|
|
||||||
|
out->dq_ref.q = align->cfg.volt;
|
||||||
|
out->dq_ref.d = 0.0f;
|
||||||
|
out->vdq_comp.q = 0.0f;
|
||||||
|
out->vdq_comp.d = 0.0f;
|
||||||
|
out->angle = align->index_angle;
|
||||||
|
out->foc_mode = FOC_HANDLER_MODE_VOLTAGE;
|
||||||
|
|
||||||
|
/* Increase counter */
|
||||||
|
|
||||||
|
align->cntr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: foc_align_offset_run_f32
|
* Name: foc_align_offset_run_f32
|
||||||
*
|
*
|
||||||
@ -711,6 +866,29 @@ int foc_routine_align_run_f32(FAR foc_routine_f32_t *r,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_INDUSTRY_FOC_ALIGN_INDEX
|
||||||
|
case FOC_ALIGN_RUN_INDEX:
|
||||||
|
{
|
||||||
|
/* Align zero procedure */
|
||||||
|
|
||||||
|
ret = foc_align_index_run_f32(a, in, out);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == FOC_ROUTINE_RUN_DONE)
|
||||||
|
{
|
||||||
|
FOCLIBLOG("ALIGN INDEX done!\n");
|
||||||
|
|
||||||
|
a->stage += 1;
|
||||||
|
ret = FOC_ROUTINE_RUN_NOTDONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case FOC_ALIGN_RUN_OFFSET:
|
case FOC_ALIGN_RUN_OFFSET:
|
||||||
{
|
{
|
||||||
/* Align zero procedure */
|
/* Align zero procedure */
|
||||||
|
Loading…
Reference in New Issue
Block a user