模拟实现一个T型速度曲线的运动

实现单轴的T型速度曲线相对运动指令点位运动

开发工具:vs2019

核心算法写在DLL动态链接库中

 

 

这是速度曲线,为啥会这样

核心代码有点多,不好粘贴,有请各位大佬来讨论

您好,我是有问必答小助手,你的问题已经有小伙伴为您解答了问题,您看下是否解决了您的问题,可以追评进行沟通哦~

如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~

ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632

MFC部分代码 

void CTmymfcDlg::OnBnClickedButton1() //位移曲线
{
	//提取编辑框中输入的参数
	flag = 1;
	GetDlgItem(IDC_EDIT7)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit7 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT8)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit8 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT9)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit9 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT10)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit10 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT11)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i]; 
	}
	nEdit11 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT12)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit12 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));
	// TODO: 在此添加控件通知处理程序代码
	T_Position(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11, y1Values,nEdit12);
	nSize = T_length(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11,nEdit12);
	SetTimer(1, 1, NULL);
	//delete[]y1Values;
	k = 1;

}


void CTmymfcDlg::OnBnClickedOk() //确定曲线
{
	// TODO: 在此添加控件通知处理程序代码
	delete[]y1Values;
	CDialogEx::OnOK();
}


void CTmymfcDlg::OnTimer(UINT_PTR nIDEvent)  //定时器
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch (nIDEvent)
	{
	case 1:

		if (k == nSize+1)
		{
			KillTimer(1);
			break;
		}
		for (i = 0; i <= k; i++)
		{
			x1Values[i] = i;
		}

		m_ChartCtrl1.SetZoomEnabled(true);
		m_ChartCtrl1.RemoveAllSeries();//清空
		pLineserie1 = m_ChartCtrl1.CreateLineSerie();
		pLineserie1->SetSeriesOrdering(poNoOrdering);//无序
		pLineserie1->SetPoints(x1Values, y1Values, k);
		k++;
	case 2:
		
		if (k == nSize+1)
		{
			KillTimer(2);
			break;
		}
		for (i = 0; i <= k; i++)
		{
			x1Values[i] = i;
		}

		m_ChartCtrl1.SetZoomEnabled(true);
		m_ChartCtrl1.RemoveAllSeries();//清空
		pLineserie1 = m_ChartCtrl1.CreateLineSerie();
		pLineserie1->SetSeriesOrdering(poNoOrdering);//无序
		pLineserie1->SetPoints(x1Values, y1Values, k);
		k++;
	case 3:	
		if (k == nSize+1)
		{
			KillTimer(3);
			break;
		}
		for (i = 0; i <= k; i++)
		{
			x1Values[i] = i;
		}

		m_ChartCtrl1.SetZoomEnabled(true);
		m_ChartCtrl1.RemoveAllSeries();//清空
		pLineserie1 = m_ChartCtrl1.CreateLineSerie();
		pLineserie1->SetSeriesOrdering(poNoOrdering);//无序
		pLineserie1->SetPoints(x1Values, y1Values, k);
		k++;

	case 4:
		if (k == nSize + 1)
		{
			KillTimer(4);
			break;  
		}

		m_ChartCtrl1.SetZoomEnabled(true);
		//m_ChartCtrl1.RemoveAllSeries();//清空
		pLineserie1 = m_ChartCtrl1.CreateLineSerie();
		pLineserie1->SetSeriesOrdering(poNoOrdering);//无序
		pLineserie1->SetPoints(x1Values, y1Values,k);
		k++;
	default:
		break;
	}

}


void CTmymfcDlg::OnBnClickedButton2()
{
	//提取编辑框中输入的参数
	flag = 2;
	GetDlgItem(IDC_EDIT7)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit7 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT8)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit8 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT9)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit9 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT10)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit10 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT11)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit11 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT12)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit12 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));
	T_Velocity(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11, y1Values,nEdit12);
 	nSize = T_length(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11,nEdit12);
	// TODO: 在此添加控件通知处理程序代码
	SetTimer(2, 1, NULL);
	k = 1;

}


void CTmymfcDlg::OnBnClickedButton3()
{
	//提取编辑框中输入的参数
	flag = 3;
	GetDlgItem(IDC_EDIT7)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit7 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT8)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit8 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT9)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit9 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT10)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit10 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT11)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit11 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));

	GetDlgItem(IDC_EDIT12)->GetWindowTextW(szEdit);
	for (i = 0; i < szEdit.GetLength(); i++)
	{
		cEdit[i] = szEdit[i];
	}
	nEdit12 = atof(cEdit);
	szEdit.Empty();
	memset(cEdit, '\0', sizeof(cEdit));
	// TODO: 在此添加控件通知处理程序代码
	T_Acceleration(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11, y1Values,nEdit12);
	nSize = T_length(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11,nEdit12);
	SetTimer(3, 1, NULL);
	k = 1;

}


void CTmymfcDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	if (flag == 1)
	{
		KillTimer(1);
	}
	else if (flag == 2)
	{
		KillTimer(2);
	}
	else if (flag == 3)
	{
		KillTimer(3);
	}
	if (flag2 == 1)
	{
		KillTimer(4);
	}

	//m_ChartCtrl1.SetZoomEnabled(true);
	//m_ChartCtrl1.RemoveAllSeries();//清空
	//pLineserie1 = m_ChartCtrl1.CreateLineSerie();
	//pLineserie1->SetSeriesOrdering(poNoOrdering);//无序
	//pLineserie1->SetPoints(x1Values, y1Values, k - 1);
}


void CTmymfcDlg::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	if (flag == 1)
	{
		T_Positionx(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11, y1Values,k-2);
		nSize = T_lengthx(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11, k-2);
	}
	else if (flag == 2)
	{
		T_Velocityx(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11, y1Values,k-2);
		nSize = T_lengthx(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11, k-2);
	}
	else if (flag == 3)
	{
		T_Accelerationx(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11, y1Values,k-2);
		nSize = T_lengthx(nEdit7, nEdit8, nEdit9, nEdit10, nEdit11, k-2);
	}
	flag2 = 1;
	a = k - 2;
	for (i = 0; i <= nSize; i++)
	{
		x1Values[i] = a + i;
	}
	k = 1;
	SetTimer(4, 1, NULL);
	//flag2 = 0;
	k = 1;

}

 DLL一个接口函数(位移)

double * T_Position(double nDistance, double nStartVelocity, double nMaxVelocity, double nAcceleration, double nDeceleration, double* p,double x)
{
	double nStartPosition = 0;//起始位置
	double nTime = 0;//起始时间
	double nStopVelocity = 0;//停止速度
	double nFeasibleVelocity = 0;//可达到的最大速度
	double nVelocity = 0; //匀速速度
	double nAcTime = 0;//加速时间
	double nAvgTime = 0;//匀速时间
	double nDeTime = 0;//减速时间
	double nAcVelocity = 0;//加速位移
	double nAvgVelocity = 0;//匀速位移
	double nDeVelocity = 0;//减速位移
	double nTimer = x;//计时
	double i = 0;//循环变量
	int k = 0;

	//公式求可达到的最大速度
	nDistance += nStartPosition;
	nFeasibleVelocity = sqrt((2.0 * nAcceleration * nDistance + nStartVelocity * nStartVelocity+ nStopVelocity * nStopVelocity) / 2);

	//确定匀速阶段速度
	if (nMaxVelocity < nFeasibleVelocity)
	{
		nVelocity = nMaxVelocity;
	}
	else
	{
		nVelocity = nFeasibleVelocity;
	}

	//计算加速阶段时间和位移
	nAcTime = (nVelocity - nStartVelocity) / nAcceleration;
	nAcVelocity = nStartVelocity * nAcTime + (1.0 / 2.0) * nAcceleration * nAcTime * nAcTime;

	//计算匀速阶段的时间和位移
	nAvgTime = (nDistance - (nVelocity * nVelocity - nStartVelocity * nStartVelocity) / (2.0 * nAcceleration)- (nStopVelocity * nStopVelocity - nVelocity * nVelocity) / (2.0 * -nDeceleration)) / nVelocity;
	nAvgVelocity = nVelocity * nAvgTime;

	//计算减速阶段的时间和位移
	nDeTime = (nVelocity - nStopVelocity) / nDeceleration;
	nDeVelocity = nVelocity * nDeTime - (nDeceleration * nDeTime * nDeTime) / 2;

	//计算轨迹的离散点位
	nTime = nAcTime + nAvgTime + nDeTime;
	for (i = 0, k = 0; i <= nTime; i += nTimer, k++)
	{
		if (i >= 0 && i < nAcTime)
		{
			p[k] = nStartPosition + nStartVelocity + (nAcceleration * i * i) / 2;
		}
		else if (i >= nAcTime && i < nAcTime + nAvgTime)
		{
			p[k] = nStartPosition + nAcVelocity + nVelocity * (i - nAcTime);
		}
		else if (i >= nAvgTime + nAcTime && i <= nTime)
		{
			p[k] = nStartPosition + nAcVelocity + nAvgVelocity + nVelocity * (i - nAcTime - nAvgTime)- nDeceleration * (i - nAcTime - nAvgTime) * (i - nAcTime - nAvgTime) / 2;
		}
		else
		{
			p[k] = 0;
		}
		
	}

	return p;
	
}