Line.c 12.5 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
#include "hardware.h"
#include "all_value.h"



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



float OverrideAuto_Go;
float Override1Auto_Go=1.2f;
u8 Override2Auto_Go=2;
u8 OverrideMinAuto_Go=4;
u8 OverrideMaxAuto_Go=55;
float AutoRadius;
#define Dis0_Delta 3.5f
#define  Dis1_Delta 4.0f
#define  Dis2_Delta 60.0f
u8 F_OverrideGo_KZ=0 ;//空载速度 百分比
u8 F_OverrideGo_FZ=0 ;//负载速度 百分比
float R1_A=32000;
float R2_A=24000;

#define R1_Max 30000.0f  
#define R1_Min 22000.0f 

#define R2_Max 35000.0f  
#define R2_Min 25000.0f 

#define R3_Max 41000.0f  
#define R3_Min 33000.0f 
#define OverrideLow1TJ_Go 40.0f
#define OverrideLow2TJ_Go 50.0f



u8 Tim5_PDNums;//用于无按键操作下的计时
#define LowAutoSp 200.0f //mm/s 速度低于此值时不再减速
#define LowAutoSp2 100.0f //mm/s 速度低于此值时不再减速
#define DisMax_FZ 3000.0f //开始减速的最大距离
#define DisMax_KZ 1600.0f //开始减速的最大距离
#define DisMin 180.0f //线性调整的最小距离
#define AccTime_FZ 300.0f //车中心负载加速时间单位10ms
#define AccTime_KZ 200.0f //车中心空载加速时间单位10ms
#define DccTime_FZ 160.0f //车中心负载减速时间单位10ms
#define DccTime_KZ 50.0f //车中心空载减速时间单位10ms
u16 Tim4_AccDccNums;//加速时间间隔计数
#define Dx_Max 250 //允许最大偏差量
# define LR_SafeEn 1 //雷达安全保护-减速启用
void Line1_Pro(void)//获取工作模式
{
	u8 i;
  float f1;//临时速度变量
	float DisMax;
	float AccTime,DccTime;
	float Ang_LineGo;//路线的角度
	s8 LineDir;
	switch(AGV.Line_Step)
	{	
		case 1://舵轮组检查

					AGV.AxisEn_Step=1;
					AGV.Axis_No=0x3E;//外加6号输送轴或者移栽轴
					AGV.Line_Step++;
					FirstPosOk=0;
					break;
		case 2://舵轮组都已使能
					if (AGV.AxisEn_Step==100)AGV.Line_Step=4;
					break;	
		case 4://计算行走方向
					if ( VaIndexB_R(&SlamMess_Fresh,4) && (Status_SlamLaser==2) )//
					{	if( Dis_CalculateLine(AgvSP,EndPoint)<65) AGV.Line_Step=90;
						else
   					{ if(VaIndexB_R(&AGV.OtheSta,2))
							{
								Ang_LineGo=AGV.RouteAngDir=Ang_CalculateLine(LastEndP,EndPoint);
								StartPoint=LastEndP;
							}
							else
							{
								Ang_LineGo=AGV.RouteAngDir=Ang_CalculateLine(AgvSP,EndPoint);
								StartPoint=AgvSP;
							}
							
							AGV.DirGo=DirGo_Calculate(Ang_SlamAgv,Ang_LineGo);								
							if (AGV.DirGo!=0)
							{ if(Ceshi[18]==1)
								{ F_Un.A_Slam_T=Ang_LineGo;
									AGV.DirGo=2;
								}
								else//期望车角度
								{ F_Un.A_Slam_T=Ang_LineGo-((float)AGV.DirGo-2)*90.0f;
									AngDeal(&F_Un.A_Slam_T);
								}								
								if( Dis_CalculateLine(AgvSP,EndPoint)>500)AGV.Line_Step++;	
								else AGV.Line_Step=11;
							}	
							
						}

						
						VaIndexB_W(&SlamMess_Fresh,4,0);
					}					
					break;
										
		case 5://
					if ( ActionAutoEn|(ManuConfirm==1) )
					{  
						if( ((AGV.RouteP[0].P_Type1==3)|(AGV.RouteP[0].P_Type1==4))&&     //1->行进普通点;2->拐点;3-充电点;4->工位料台;5->进工位料台前点;25->拐点+料台前点;
							  (Dis_CalculateLine(AgvSP,EndPoint)<3000)
   						 )Ang_MaxDelta=220;//*0.01度
 						else Ang_MaxDelta=500;//*0.01度  

						AGV.RotationSlam_Step=1;
					  AGV.Line_Step++;
						ManuConfirm=0;
					}
					break;		
		case 6://完成旋转
					if (AGV.RotationSlam_Step==100)
					{ 
						Motor[2].PcToM.AbsoluteHold_Step=Motor[4].PcToM.AbsoluteHold_Step=0;					
						AGV.Line_Step++;}
					break;		
		case 7://行走轴置零
					Motor[1].PcToM.SetZero_Step=Motor[3].PcToM.SetZero_Step=1;
					AGV.Line_Step++;
					break;					
		case 8://判断是否完成置零
					if( (Motor[1].PcToM.SetZero_Step==100) && (Motor[3].PcToM.SetZero_Step==100) )
					AGV.Line_Step=13;
					break;		
		case 11://SLAM微调  考虑此处将行走轴置零
						AGV.Load_Step=1;
						AGV.Type2_AdLev=2;
						AGV.Line_Step++;
						VaIndexB_W(&AGV.OtheSta,3,0);
					break;	
		case 12://微调完成
					if (AGV.Load_Step==100)AGV.Line_Step=90;		
					break;			
		case 13:	
					for(i=1;i<5;i++)
					{
						Motor[i].PcToM.Acc=1000;
						Motor[i].PcToM.Dcc=1000;	
					}	
					AGV.Line_Step++;
					break;							
		case 14://舵轮调整
					if( (AGV.DirGo==2)|(AGV.DirGo==4) )
					{ Motor[2].PcToM.Angle_Target=Motor[4].PcToM.Angle_Target=90;}
					else
					{ Motor[2].PcToM.Angle_Target=Motor[4].PcToM.Angle_Target=0;}
					
					Motor[2].PcToM.AbsoluteHold_Enable=Motor[4].PcToM.AbsoluteHold_Enable=1;						
					Motor[2].PcToM.AbsoluteHold_Step=Motor[4].PcToM.AbsoluteHold_Step=1;
					AGV.Line_Step++;
					break;	
		case 15://舵轮角度调到位
					if ( (fabs(Motor[2].MToPc.Angle_Actual-Motor[2].PcToM.Angle_Target)<DeltaAngPerm_Helmzhuan)&&(Motor[2].PcToM.AbsoluteHold_Step==20) &&
               (fabs(Motor[4].MToPc.Angle_Actual-Motor[4].PcToM.Angle_Target)<DeltaAngPerm_Helmzhuan)&&(Motor[4].PcToM.AbsoluteHold_Step==20)		)
							AGV.Line_Step++;
					
					Tim4_AccDccNums=0;
					break;		

		case 16://走

					if (VaIndexB_R(&AGV.OtheSta,0))//有负载
				  { 
						if(F_OverrideGo_FZ>2&&F_OverrideGo_FZ<80)OverrideMaxAuto_Go=F_OverrideGo_FZ;
						else OverrideMaxAuto_Go=30;
						AccTime=AccTime_FZ;
						DccTime=DccTime_FZ;
						DisMax=DisMax_FZ;
					}
					else 
					{ if(F_OverrideGo_KZ>5&&F_OverrideGo_KZ<80)OverrideMaxAuto_Go=F_OverrideGo_KZ;
						else OverrideMaxAuto_Go=40;
						AccTime=AccTime_KZ;
						DccTime=DccTime_KZ;
						DisMax=DisMax_KZ;
					}


					if (Dis_GoBackLine>DisMax){ OverrideAuto_Go=(float)OverrideMaxAuto_Go;}	
					else if(Dis_GoBackLine>DisMin)
						{ OverrideAuto_Go=((float)OverrideMaxAuto_Go-(float)OverrideMinAuto_Go)/(DisMax-DisMin)*(Dis_GoBackLine-DisMin)+(float)OverrideMinAuto_Go;}
				  else if (Dis_GoBackLine>50){ OverrideAuto_Go=(float)Override2Auto_Go;}						 
					else { OverrideAuto_Go=Override1Auto_Go;}
						 
						 
					if(fabs(DelX_HVP_Line)>Dx_Max){;}
					else Tim5_PDNums=0;
						 



					if(Status_SlamLaser!=2)//置信度不高时减速
					{ OverrideAuto_Go=OverrideAuto_Go*0.6f;
						
					}


					#if(LR_SafeEn==1)					
							if(LRadar_Far)//远处有障碍物且速度过大时减速
							{ 
								if( (OverrideAuto_Go*0.01f*Motor[1].Max_Speed)>LowAutoSp )OverrideAuto_Go=LowAutoSp*100.0f/Motor[1].Max_Speed;	
								
							}
							if(LRadar_Middle)//中区域检测到再次减速
							{ if((OverrideAuto_Go*0.01f*Motor[1].Max_Speed)>LowAutoSp2 )OverrideAuto_Go=LowAutoSp2*100.0f/Motor[1].Max_Speed;
								DccTime=50;
							}
					#endif	
	
					if(VaIndexDW_R(&F_AgvContr,10)&& VaIndexB_R(&AGV.OtheSta,5)&&(VaIndexDW_R(&Touch_Contr,9)==0))
					{ OverrideAuto_Go=0;Set_ErrID(39,1);}//滚筒限位触发
					
					if(Tim5_Slam3Nums>1)OverrideAuto_Go=0;//置信度不高超时停止
					if(Tim5_PDNums>2)//偏差过大超过2s则停止运行
					{ OverrideAuto_Go=0;
						Set_ErrID(46,1); //ErrID=46;行走过程横向偏差过大
					}
					
					
					/*减速过程调节速度*/					
					if ( abs(Motor[1].MToPc.speed)>(OverrideAuto_Go*0.01f*(float)Motor[1].Max_rpm+60) ) 				
					{ 
						f1=fabs(Motor[1].MToPc.speed)*100.f/(float)Motor[1].Max_rpm-(float)Tim4_AccDccNums/DccTime*100.0f;								
						if( f1>=OverrideAuto_Go )
						{ 
							 OverrideAuto_Go=f1;
						}
							
					}
					
					/*加速过程调节速度*/             
					if ( (abs(Motor[1].MToPc.speed)+50) <(OverrideAuto_Go*0.01f*(float)Motor[1].Max_rpm) ) 			
					{ 
						f1=fabs(Motor[1].MToPc.speed)*100.f/(float)Motor[1].Max_rpm+(float)Tim4_AccDccNums/AccTime*100.0f;								

						if( f1<1 )OverrideAuto_Go=1;
						else if( f1<OverrideAuto_Go )OverrideAuto_Go=f1;
					}

					Tim4_AccDccNums=0;
					
					
					/*根据速度和负载确定调节半径范围*/
					if (abs(Motor[1].MToPc.speed)<(OverrideLow1TJ_Go*0.01f*(float)Motor[1].Max_rpm) ) 
					{ R1_A=R1_Max;
						R2_A=R1_Min;						
				  }
					else if (abs(Motor[1].MToPc.speed)<(OverrideLow2TJ_Go*0.01f*(float)Motor[1].Max_rpm) ) 
					{ if (VaIndexB_R(&AGV.OtheSta,0))
						{ R1_A=R3_Max;
						  R2_A=R3_Min;	}
						else
						{ R1_A=R2_Max;
						  R2_A=R2_Min;}
				  }	
					else
					{ R1_A=R3_Max;
						R2_A=R3_Min;						
				  }		
					
					/*根据点偏差确定弧半径*/
					if (fabs(DelX_HVP_Line)<Dis0_Delta)
					{ 
							if(AGV.DirGo==1)Fc_Matrix_Agv(OverrideAuto_Go*0.01f*Motor[1].Max_Speed,0,0,0,0,0);						 
							else if(AGV.DirGo==2)Fc_Matrix_Agv(0,OverrideAuto_Go*0.01f*Motor[1].Max_Speed,0,0,0,0);	
							else if(AGV.DirGo==3)Fc_Matrix_Agv(-OverrideAuto_Go*0.01f*Motor[1].Max_Speed,0,0,0,0,0);
							else if(AGV.DirGo==4)Fc_Matrix_Agv(0,-OverrideAuto_Go*0.01f*Motor[1].Max_Speed,0,0,0,0);
					}
					else 
					{ 	if (DelX_HVP_Line>0)LineDir=-1;
							else LineDir=1;
							
							if (fabs(DelX_HVP_Line)<Dis1_Delta)AutoRadius=R1_A;
							else if (fabs(DelX_HVP_Line)<Dis2_Delta)AutoRadius=(fabs(DelX_HVP_Line)-Dis1_Delta)/(Dis2_Delta-Dis1_Delta)*(R2_A-R1_A)+R1_A;		
							else AutoRadius=R2_A;
							
							if(OverrideAuto_Go==0){LineDir=0;AutoRadius=0;}
							
							if(AGV.DirGo==1)Fc_Matrix_Agv(OverrideAuto_Go*0.01f*Motor[1].Max_Speed,0,(float)LineDir,AutoRadius,0,0);						 
							else if(AGV.DirGo==2)Fc_Matrix_Agv(0,OverrideAuto_Go*0.01f*Motor[1].Max_Speed,(float)LineDir,AutoRadius,0,0);	
							else if(AGV.DirGo==3)Fc_Matrix_Agv(-OverrideAuto_Go*0.01f*Motor[1].Max_Speed,0,(float)LineDir,AutoRadius,0,0);
							else if(AGV.DirGo==4)Fc_Matrix_Agv(0,-OverrideAuto_Go*0.01f*Motor[1].Max_Speed,(float)LineDir,AutoRadius,0,0);						 
					}

								
						
					if (Dis_GoBackLine<4)
					{ Fc_Matrix_Agv(0,0,0,0,0,0);
							Motor[2].PcToM.AbsoluteHold_Step=Motor[4].PcToM.AbsoluteHold_Step=0;
							Motor[2].PcToM.AbsoluteHold_Enable=Motor[4].PcToM.AbsoluteHold_Enable=0;
							Motor[2].PcToM.TargetSpeed=Motor[4].PcToM.TargetSpeed=0;
							AGV.Line_Step++;
					}

//					
					if (((AGV.TaskManu_Step==0)|(AGV.TaskManu_Step==100)) )//
					{		
						if (AGV.RouteP[1].Code )//判断是否需要更新目标点
						{ 
								if(AGV.RouteP[0].SP.Ang|AGV.RouteP[0].P_AD_Type2|(AGV.RouteP[0].P_AC_Type3>1)){;}//把当前点走完
								else
								{ 
									Ang_LineGo=AngDelta_Calculate(AGV.RouteAngDir,Ang_CalculateLine(AGV.RouteP[0].SP,AGV.RouteP[1].SP));
									if( (fabs(Ang_LineGo)<AngLineDeltaMax)|
											((fabs(Ang_LineGo)<=AngLineDuanDeltaMax)&& Dis_CalculateLine(AGV.RouteP[0].SP,AGV.RouteP[1].SP)<=400)//行驶方向角度变化不大
										)
									{ 										
//										StartPoint=AGV.RouteP[0].SP;
										RouteGoAcPMiss_fc();
										EndPoint=AGV.RouteP[0].SP;
										AGV.RouteAngDir=Ang_CalculateLine(StartPoint,AGV.RouteP[0].SP);										
									}
								}							
						}						
					}
					
					if (AGV.RouteP[0].Code )//判断完成状态是否需要清除
					{
						if(VaIndexB_R(&AGV.OtheSta,3) ){ if(Dis_GoBackLine<400)VaIndexB_W(&AGV.OtheSta,3,0);}						
						else if(Dis_GoBackLine>400)
						{ for(i=0;i<4;i++)
							{ if(TaskP[i].Code==AGV.VirCode)
								{VaIndexB_W(&AGV.OtheSta,3,1);break;}															
							}
						}							
					}											
					break;		
		case 17://
					AGV.Line_Step=90;
					break;				
		case 90://走完
					VaIndexB_W(&AGV.OtheSta,2,1);
					LastEndP=EndPoint;
		
					AGV.Line_Step=100;									
					break;
		case 100://
					break;
	}		
	if(AGV.Line_Step>0&&AGV.Line_Step<100)HeadRun_PoCal_Pro();
	
}





	




#define Dis_HVP_AgvC 1200.0f//纠偏时车头点到车中心的设定距离


float Dis_GoBackLine;//剩余还未走的距离	
float DelX_HVP_Line;//行驶偏差
void HeadRun_PoCal_Pro(void)//行驶偏差计算函数
{	

	float Dis_GoDoneLine;//已走距离

	float Ang_HVP_S;
	float Ang_SH_Line;
	float Ang_SE_Line;
	float Ang_HSE_Line;
		
	float Ang_SC_Line;
	float Ang_CSE_Line;
	Str_SlamPoint  HVPoint;
		
	if ( VaIndexB_R(&SlamMess_Fresh,4) && (Status_SlamLaser==2) )
	{

		Ang_HVP_S=((float)AGV.DirGo-2)*90.0f+Ang_SlamAgv;
		AngDeal(&Ang_HVP_S);	
		HVPoint.X_Slam=AgvSP.X_Slam+Dis_HVP_AgvC*cos(Ang_HVP_S*Pi_Du);
		HVPoint.Y_Slam=AgvSP.Y_Slam+Dis_HVP_AgvC*sin(Ang_HVP_S*Pi_Du);	

	
		Ang_SH_Line=Ang_CalculateLine(StartPoint,HVPoint);	
		Ang_SE_Line=Ang_CalculateLine(StartPoint,EndPoint);
		Ang_HSE_Line=AngDelta_Calculate(Ang_SE_Line,Ang_SH_Line);
		DelX_HVP_Line=Dis_CalculateLine(StartPoint,HVPoint)*sin(Ang_HSE_Line*Pi_Du);//负值为在左侧	
		
		

		
		
		/*已走的距离+剩余距离*/		
		Ang_SC_Line=Ang_CalculateLine(StartPoint,AgvSP);
		Ang_CSE_Line=AngDelta_Calculate(Ang_SE_Line,Ang_SC_Line);

		Dis_GoDoneLine=Dis_CalculateLine(StartPoint,AgvSP)*cos(Ang_CSE_Line*Pi_Du);
		Dis_GoBackLine=Dis_CalculateLine(StartPoint,EndPoint)-Dis_GoDoneLine;

		
		
		VaIndexB_W(&SlamMess_Fresh,4,0);
	}
	
}






u8 DirGo_Calculate(float Ang_C,float Ang_Go)//车行驶方向选择函数
{
	float AngDelta;
	u8 Dir;
	u8 i;
	float AngDir;

	Dir=0;
	for(i=1;i<5;i++)
	{ AngDir=((float)i-2)*90.0f+Ang_C;
		AngDeal(&AngDir);
		AngDelta=AngDelta_Calculate(Ang_Go,AngDir);
		if(fabs(AngDelta)<=45) { Dir=i;break; }
		
	}
	return	Dir; 
}