Rotation.c 7.75 KB
#include "hardware.h"
#include "all_value.h"



/*********************************************************************************
函数名:
功能:
参数:
返回:无返回。
实现方法:
编程:
日期:2021-12-16
*********************************************************************************/

#define AngInDeltaEn    1u//调节后角度必须在范围内


float AngLineTarget;
u16 Ang_MaxDelta;//单位0.01度
void RotationSlam_Pro(void)//
{	float Ang_Delta;
	switch(AGV.RotationSlam_Step)
	{	
		case 1://	
					AGV.AxisEn_Step=1;
					AGV.Axis_No=0x3E;

					AGV.RotationSlam_Step++;
					break;
		case 2://舵轮组都已使能
					if (AGV.AxisEn_Step==100)AGV.RotationSlam_Step=10;
					break;					
		case 10:
					VaIndexB_W(&SlamMess_Fresh,4,0);
					AGV.RotationSlam_Step++;
					break;	
		case 11://	SLAM最新信息且信息可靠	计算走距离量
					if ( VaIndexB_R(&SlamMess_Fresh,4) && (Status_SlamLaser==2) )
					{ 
 							Ang_Delta=AngDelta_Calculate(Ang_SlamAgv,F_Un.A_Slam_T);
							if( fabs(Ang_Delta) <(float)Ang_MaxDelta*0.01f )AGV.RotationSlam_Step=90;//车姿与目标角度偏差过小,故不调整
							else 
							{ 
								Motor[3].PcToM.Angle_Target=Ang_Delta*Pi_Du*(float)Dis_AgvC_Helm*0.98f;
								Motor[1].PcToM.Angle_Target=-Motor[3].PcToM.Angle_Target;
								Motor[2].PcToM.AbsoluteHold_Enable=Motor[4].PcToM.AbsoluteHold_Enable=0;
								Motor[2].PcToM.Angle_Target=Motor[4].PcToM.Angle_Target=AngCw_Helm;	
								AGV.RotationSlam_Step=20;//需要调整车身角度姿态
							}							
						
					}
					break;
 		case 20://启动舵轮转走一定距离
						AGV.GoDis_Step=1;
						AGV.RotationSlam_Step++;
						break;					
		case 21://判断是否完成
						if(AGV.GoDis_Step==100)AGV.RotationSlam_Step++;
						break;							
		case 22://跳回判断角度偏差是否达到目标允许偏差范围		
						if(AngInDeltaEn)
							AGV.RotationSlam_Step=10;
						else AGV.RotationSlam_Step=90;
						break;			
		case 90://
					  AGV.RotationSlam_Step=100;
					  break;
		case 100://完成动作
					  break;

	}

//	if ( (AGV.Rotation_Step==0)|(AGV.Rotation_Step==100) )AGV.Rotation_Time5Nums=0;
//	if(AGV.Rotation_Time5Nums>RotationPermitDelay_Time){;}	
;	
}



Union_Target F_Un;

u8 ceshi782=0;
void RotationCCD_Pro(void)
{
	float Ang_Delta;
	switch(AGV.RotationCCD_Step)
	{	
		case 1://	
					AGV.AxisEn_Step=1;
					AGV.Axis_No=0x3E;
					AGV.RotationCCD_Step++;	
					VaIndexB_W(&AGV.OtheSta1,2,0);
					break;
		case 2://舵轮组都已使能
					if (AGV.AxisEn_Step==100)AGV.RotationCCD_Step=10;
					break;		
		case 10://根据相机当前角度计算旋转量
					VaIndexB_W(&AGV.OtheSta1,0,1);

					if(CCD_M[CameraNo].CodeOn)//0-下视觉;1-上视觉
					{ Ang_Delta=AngDelta_Calculate(CCD_M[CameraNo].Ang,F_Un.A_CCD_T);
								
						if( fabs(Ang_Delta)<=(float)Ang_MaxDelta*0.01f )AGV.RotationCCD_Step=90;//车姿与目标角度偏差过小,故车身角度不调整
						else 
						{ if(CameraNo)Ang_Delta=0-Ang_Delta;
							Motor[3].PcToM.Angle_Target=Ang_Delta*Pi_Du*(float)Dis_AgvC_Helm;
							Motor[1].PcToM.Angle_Target=-Motor[3].PcToM.Angle_Target;

							Motor[2].PcToM.AbsoluteHold_Enable=Motor[4].PcToM.AbsoluteHold_Enable=0;
							Motor[2].PcToM.Angle_Target=Motor[4].PcToM.Angle_Target=AngCw_Helm;	
							AGV.RotationCCD_Step=20;//需要调整车身角度姿态
						}
					}
					break;						
 		case 20://启动舵轮转走一定距离
						AGV.GoDis_Step=1;
						AGV.RotationCCD_Step++;
						break;					
		case 21://判断是否完成车身旋转
						if(AGV.GoDis_Step==100)AGV.RotationCCD_Step++;
						break;						
		case 22://跳回判断角度偏差是否达到目标允许偏差范围		
						if(AngInDeltaEn)
							AGV.RotationCCD_Step=10;
						else AGV.RotationCCD_Step=90;
						break;	
		case 90://
					  AGV.RotationCCD_Step=100;
					  break;
		case 100://完成动作
					  break;

	}
	
}

void AgvGoDis_Pro(void)//舵轮走一定距离函数
{
	switch(AGV.GoDis_Step)
	{	
		case 1://	
					AGV.AxisEn_Step=1;
					AGV.Axis_No=0x3E;
					AGV.GoDis_Step++;
					break;
 		case 2://舵轮组都已使能
					if (AGV.AxisEn_Step==100){ AGV.GoDis_Step=20;ManuConfirm=0;}
					break;		
		case 20://舵轮转向轴调至相应姿态
						if ( ActionAutoEn|(ManuConfirm==1) )
						{
							if( VaIndexB_R(&AGV.AllAxisOK,2) )
							{ 
								Motor[2].PcToM.AbsoluteHold_Step=Motor[4].PcToM.AbsoluteHold_Step=1;
								Motor[2].PcToM.AbsoluteHold_Enable=Motor[4].PcToM.AbsoluteHold_Enable=0;
								AGV.GoDis_Step++;
							}
							ManuConfirm=0;							
						}
						break;					
		case 21://舵轮转向轴完成转向
						if( (Motor[2].PcToM.AbsoluteHold_Step==100)&&(Motor[4].PcToM.AbsoluteHold_Step==100) )
						{ 
							Motor[1].PcToM.SetZero_Step=Motor[3].PcToM.SetZero_Step=1;//车身旋转之前先将行走轴清零
							AGV.GoDis_Step++;}
						break;					
		case 22://判断是否完成置零+启动行走轴
						if (ActionAutoEn|(ManuConfirm==1))
						{			
							if( (Motor[1].PcToM.SetZero_Step==100) && (Motor[3].PcToM.SetZero_Step==100) )
							{ Motor[1].PcToM.SpeedAbsolute_Step=Motor[3].PcToM.SpeedAbsolute_Step=1;
								AGV.GoDis_Step++;
							}
							ManuConfirm=0;							
						}
						break;

		case 23://判断行走轴是否完成
						if((Motor[1].PcToM.SpeedAbsolute_Step==100) && (Motor[3].PcToM.SpeedAbsolute_Step==100) )AGV.GoDis_Step++;
						break;						
		case 24:		
						AGV.GoDis_Step=90;
						break;	
		case 90://
					  AGV.GoDis_Step=100;
					  break;
		case 100://完成动作
					  break;

	}
	
}


float AngDelta_Calculate(float Ang_S,float Ang_E)//目标终止相对起始的偏角。正值为目标偏左
{
	float AngDelta;
	AngDelta=Ang_E-Ang_S;//目标角度减去起始角度
	if ( fabs(AngDelta)>180 )
	{ if( (AngDelta)>0 ) AngDelta=AngDelta-360;
		else AngDelta=AngDelta+360;		
	}
	if (AngDelta==-180.0f )AngDelta=180.0f;
	return AngDelta;
}



#define DxlinePer    100//mm

float Ang_CalculateLine(Str_SlamPoint P_S,Str_SlamPoint P_E)////根据起始点和终止点计算该直线的角度(0-360)
{
	float AngT;
  float Dx,Dy;	
	Dx=P_E.X_Slam-P_S.X_Slam;
	Dy=P_E.Y_Slam-P_S.Y_Slam;

	

	if( fabs(Dx)==0)//X方向偏差小,可以认为走Y方向上
	{ if(Dy>0)AngT=90;
		else if(Dy<0) AngT=270;
		else AngT=0;

	}	
	else 	if( fabs(Dy)==0)//Y方向偏差小,可以认为走X方向上
	{ if(Dx>0)AngT=0;
		else AngT=180;
	}	
	else
	{ AngT=atan(Dy/Dx)*Du_Pi;
		if(Dx<0)AngT+=180;
	}

	
	if(AngT<0)AngT+=360;	
	

	return AngT;
}

float Dis_CalculateLine(Str_SlamPoint P_S,Str_SlamPoint P_E)//根据起始点和终止点直线距离
{
	return sqrt(  pow((P_E.X_Slam-P_S.X_Slam),2)+ pow((P_E.Y_Slam-P_S.Y_Slam),2) );
}


void AxisAllEn_Pro(void)//轴使能找原点初始操作
{
	u8 i;
	u8 Ok;
	switch(AGV.AxisEn_Step)
	{	
		case 1://驱动舵轮组无故障	
					
					if ( ((AGV.Axis_No==0x3F)&&((AGV.AllAxisOK&0x0F)==0x0F))     //所有轴
					   )
					AGV.AxisEn_Step=90;//AllAxisOK:位0-AGV所有存在轴正常无故障;1-AGV所有存在轴都已使能;2-舵轮使能无故障且原点找到	;3-舵轮都使能无故障	
					else AGV.AxisEn_Step++;
					AGV.AllAct_Time5Nums=0;
					break;
		case 2://驱动舵轮使能	
				  for(i=0;i<MaxMotNums;i++)
				  { if(Motor[i].Y&&VaIndexB_R(&AGV.Axis_No,i))Motor[i].PcToM.PowerOn=1;}					
					AGV.AxisEn_Step++;
				  break;
		case 3://判断转向轴是否找到原点
					if ((Motor[2].MToPc.Home_Found==0)&&VaIndexB_R(&AGV.Axis_No,2))Motor[2].PcToM.FindHome_Step=1;
					if ((Motor[4].MToPc.Home_Found==0)&&VaIndexB_R(&AGV.Axis_No,4))Motor[4].PcToM.FindHome_Step=1;
					AGV.AxisEn_Step++;
					break;			
		case 4://需要操控的轴全部完成就绪
					Ok=1;
					for(i=0;i<MaxMotNums;i++)
				  { 						
						if(Motor[i].Y&&VaIndexB_R(&AGV.Axis_No,i)&&(Motor[i].MToPc.Powered==0))
						{ Ok=0;break;}
						
					}

					
					if (VaIndexB_R(&AGV.Axis_No,2)&& (Motor[2].MToPc.Home_Found==0))Ok=0;//轴0使能未完成
					if (VaIndexB_R(&AGV.Axis_No,4)&& (Motor[4].MToPc.Home_Found==0))Ok=0;//轴0使能未完成		
					
					if(Ok)AGV.AxisEn_Step=90;	
					VaIndexB_W(&AGV.OtheSta1,3,0);
					break;
		case 90://
					AGV.AllAct_Time5Nums=0;
					AGV.AxisEn_Step=100;
					break;
		case 100://
					break;		
	}
}
		
//Str_SlamPoint  EndPoint;

void Rotation_Pro(void)
{
	RotationCCD_Pro();
	RotationSlam_Pro();
	AgvGoDis_Pro();
}