MFC梯形加减速算法(带开根号)

31 篇文章 4 订阅

void CMOTOR_MFCDlg::OnBnClickedButton3()
{
	// TODO:  在此添加控件通知处理程序代码


#define MOTOR_LEAD	40	/* 电机模组导程,单位0.1mm */
#define STEP_PER_CIRCLE	200	/* 细分为1时,电机走一圈需要的步数 */
#define MOTOR_DRIVER_SUBDIVISION	32	/*电机驱动器细分*/
#define TIM_CLK	8000000	/* 定时器时钟频率 */

	typedef enum
	{
		MOTOR_STOP = 0,
		MOTOR_ACCELERATE,
		MOTOR_UNIFORM,
		MOTOR_DECELERATE
	}motor_run_state_typedef;

	UINT distance = 300;
	UINT speed = 100;
	UCHAR accel_time = 10;

	static UINT g_steps_total;	/* 电机总共需要运行的步数 */
	static UINT g_steps_done;	/* 电机已经运行的步数 */
	static UINT g_steps_accelerate;	/* 电机总加速运行的步数 */
	static UINT g_step_timer_pulse_num;	/* 电机运行一步需要定时器的脉冲数 */
	static UINT g_first_step_timer_pulse_num;	/* 电机运行的第一步需要定时器的脉冲数c0 */
	static UINT g_step_timer_pulse_num_min;	/* 电机运行一步需要定时器的脉冲数的最小值 */
	static UINT speed_step_per_second;
	static UINT time_sum;
	static motor_run_state_typedef motor_run_state;

	static double acceleration;

	g_steps_total = distance * STEP_PER_CIRCLE * MOTOR_DRIVER_SUBDIVISION / MOTOR_LEAD;

	if (1 == g_steps_total)
	{
		g_step_timer_pulse_num = 1000;
		motor_run_state = MOTOR_DECELERATE;
	}
	else if (0 != g_steps_total)
	{
		g_step_timer_pulse_num_min = TIM_CLK * MOTOR_LEAD * 1.0 / speed / STEP_PER_CIRCLE / MOTOR_DRIVER_SUBDIVISION;

		acceleration = speed / accel_time * 10;
		g_step_timer_pulse_num = TIM_CLK * 1.0 * sqrt(2 * MOTOR_LEAD * 1.0 / STEP_PER_CIRCLE / MOTOR_DRIVER_SUBDIVISION / acceleration);	/* 计算c0 */
		g_first_step_timer_pulse_num = g_step_timer_pulse_num;
		motor_run_state = MOTOR_ACCELERATE;
	}

	time_sum = 0;
	g_steps_done = 0;
	g_steps_accelerate = 0;
	m_pDc->MoveTo(0, m_rect.bottom / 2);

	while (1)
	{
		g_steps_done++;

		if (g_steps_done >= g_steps_total)	/* 运行完成 */
		{
			return;
		}

		switch (motor_run_state)
		{
		case MOTOR_ACCELERATE:
			if (g_steps_done * 2 > g_steps_total)
			{
				g_steps_accelerate--;
				g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0)); 
				motor_run_state = MOTOR_DECELERATE;
			}
			else if (g_steps_done * 2 == g_steps_total)
			{
				g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0));
				motor_run_state = MOTOR_DECELERATE;
			}
			else
			{
				g_steps_accelerate++;
				g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0)); 

				if (g_step_timer_pulse_num <= g_step_timer_pulse_num_min)
				{
					g_step_timer_pulse_num = g_step_timer_pulse_num_min;
					motor_run_state = MOTOR_UNIFORM;
				}
				else
				{
					motor_run_state = MOTOR_ACCELERATE;
				}
			}
			break;

		case MOTOR_UNIFORM:
			if (g_steps_total - g_steps_done <= g_steps_accelerate)
			{
				g_steps_accelerate--;
				g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0));
				motor_run_state = MOTOR_DECELERATE;
			}
			break;

		case MOTOR_DECELERATE:
			g_steps_accelerate--;
			g_step_timer_pulse_num = g_first_step_timer_pulse_num * (sqrt(g_steps_accelerate*1.0 + 1) - sqrt(g_steps_accelerate*1.0));
			break;
		}

		if (g_step_timer_pulse_num >= 0xffff)
		{
			g_step_timer_pulse_num = 0xffff;
		}
		if (g_step_timer_pulse_num == 0)
		{
			g_step_timer_pulse_num = 1;	/* 此条语句仅为调试使用,看程序是否会执行到这里 */
			return;	/* ERROR */
		}
		speed_step_per_second = TIM_CLK / g_step_timer_pulse_num;
		time_sum += g_step_timer_pulse_num;
		m_pDc->LineTo(time_sum * 0.00001, m_rect.bottom / 2 - speed_step_per_second*0.01);
	}
}

总结:
1、
在这里插入图片描述

2、将距离修改为30,UINT distance = 30;
在这里插入图片描述

3、
在这里插入图片描述
4、
在这里插入图片描述
5、
在这里插入图片描述
6、
在这里插入图片描述
7、
在这里插入图片描述
8、
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值