工程训练大赛——低经济智能物流搬运小车经验分享(二)

五、单片机部分

我们的整体思路就是将任务拆分、细化。把抓取、放置,以及转盘区、粗加工区、暂存区的逻辑等进行封装,最后整合逻辑。通过编码器电机测距到达指定地点,陀螺仪调整小车偏差角度(走直)和小车转向。

将物料抓取上车

switch(state)
	{
		case 0://爪子打开
			mission_finish = 0;
			if(round_catch_high ==1)//如果在圆盘进行抓取时,爪子张到最大,方便于摄像头识别
			Catch_SetCompare(20 );
			else 	Catch_open(0);//否则正常张开即可
			TB6612_up_dispose(0);
			TIM_Cmd(TIM6, ENABLE);
		if(round_catch_high == 0)//如果不是进行圆盘抓取则在等待一秒后进入下一个环节
		{
			if(TIM6_1000ms>1)
			{
				TIM6_1000ms = 0;
				TIM6_100ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				state = 1;
			}
		}
		else //圆盘抓取的准备事项完成了也可以进入下个标志位了,这里写的有点乱你们看着改,反正不改也能用
		state = 1;
			break;		
		case 1://下降到位
			if(round_catch_high == 0)//如果不是进行圆盘抓取
			{
				if(limit_switch() == 1)//如果触碰到底下的限位开关
				{
					Catch_open(1);//立刻抓取
					TB6612_up_dispose(0);//升降梯停止运行
					front_length = 0;//重新初始化底下的值,设定此点位为0点,方便后期电梯PID运算不会出错
					TIM2 -> CNT=0;//清0电梯编码器的计数值
				if(TIM6_100ms>5)//等待500毫秒
				{
					TIM6_100ms = 0;
					TIM_Cmd(TIM6, DISABLE);
					state = 2;//如果不是进行圆盘抓取则跳过下面两步直接跳入2
				}
				else 				TIM_Cmd(TIM6, ENABLE);
				}
				else TB6612_up_dispose(-16000); //向下运行

			}
			else//如果进行圆盘抓取
			{
				ZHUAZI_middle();//下降到圆盘抓取位置

				if(TIM6_100ms>10)//等待1秒后进行抓取
				{
					Catch_open(1);//爪子抓取
					TIM6_100ms = 0;
					TIM_Cmd(TIM6, DISABLE);
					state = 23;
				}
				else 				TIM_Cmd(TIM6, ENABLE);
			}
			break;
		case 23://抓取完成后上升到顶部
			if(TIM6_100ms>4)//此为稍微延迟让爪子抓稳
			ZHUAZI_UP();	
			if(TIM6_100ms>8)//给400ms时间上升然后跳入下个标志位
			{
				TIM6_100ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				state = 24;
			}
			else 
			TIM_Cmd(TIM6, ENABLE);
			break;
		case 24:
			TB6612_up_dispose(0);
			LobotSerialServoMove(ID1, 400, 200);  //滑轨底部舵机旋转一定的角度(并未到达物料盘),防止物料盘转动打到物料
			delay_ms(50);	
			if(TIM6_1000ms>2)
			{
				TIM6_1000ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				state = 2;
			}
			else 			TIM_Cmd(TIM6, ENABLE);
			break;
		case 2://
			ZHUAZI_UP();	//继续上升到顶

			if(TIM6_1000ms>2)
			{
				TIM6_1000ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				state = 3;
			}
			else 			TIM_Cmd(TIM6, ENABLE);
			break;
			
		case 3:

			TB6612_up_dispose(0);//电梯停止运行
			LobotSerialServoMove(ID2, ID2_mission, 200);  //物料盘旋转到对应位置
			LobotSerialServoMove(ID1, 785, 200);  //爪子旋转到物料盘的对应位置
			delay_ms(50);	
			if(TIM6_1000ms>2)
			{
				TIM6_1000ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				state = 4;
			}
			else 			TIM_Cmd(TIM6, ENABLE);
			break;
		case 4:
			ZHUAZI_put();	//放置到对应的物料盘位置

			if(TIM6_1000ms>2)
			{
				TIM6_1000ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				state = 5;
			}
			else 			TIM_Cmd(TIM6, ENABLE);
			break;
		case 5://放置仓库
			Catch_open(0);	//打开爪子防止
			TB6612_up_dispose(0);//电梯停止运行
			if(TIM6_1000ms>2)
			{
				TIM6_1000ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				state = 6;
			}
			else 			TIM_Cmd(TIM6, ENABLE);			
			break;
		case 6://放置成功
			ZHUAZI_UP();//电梯归位顶部
			if(TIM6_1000ms>2)
			{
				TIM6_1000ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				state = 7;
			}
			else 			TIM_Cmd(TIM6, ENABLE);			
			break;
		case 7://
			TB6612_up_dispose(0);//到顶部时停止运行
			LobotSerialServoMove(ID1,	100, 200);  //爪子转回抓取位置
			delay_ms(50);
			if(TIM6_1000ms>2)
			{
				TIM6_1000ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				state = 8;
			}
			else 			TIM_Cmd(TIM6, ENABLE);			
			break;		
		case 8 :
			mission_finish =1;//单次抓取任务结束,重置标志位以进行下次执行
			break;	
	}
}

将物料放置到圆环上与此类似,我就不放代码啦

转盘区

到达转盘后,我们先通过识别物料,根据色块中心调整好车身距离,再去根据获取到的抓取顺序进行抓取。

void openmv_tiaozheng(void)
 {
		 static int openmv_tiaozheng_flag = 100;
		/* ---------------------------------- 爪子打开 ---------------------------------- */
		Catch_SetCompare(20 );	
	 	 printf("%d,%d,%d,%d\r\n",openmv_tiaozheng_flag,find_cir,R_X,R_Y);
		switch(openmv_tiaozheng_flag)
		{
		case 100:
		find_cir = 2;
		{
			catching = 1; 
			LobotSerialServoMove(ID1, 100,200);  //转到正前方的位置方便识别调整
			delay_ms(50);		
			
			if(TIM7_1000ms>1)
			{
			TIM7_1000ms = 0;
			TIM7_100ms = 0;
			TIM_Cmd(TIM7, DISABLE);		TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
			openmv_tiaozheng_flag = 0;
			}	
			else 		TIM_Cmd(TIM7, ENABLE);
		}
		/* --------- 根据颜色顺序进行精准追踪中点,因为转盘的顺序为红绿蓝,
		所以识别红色离开后检测到绿色到来就必定能锁定转盘中心的位置 --------- */
		/*find_cir是识别颜色标志位,当发送识别任务函数send_mission_to_open(1)
		发送给OPENMV时,如果OPENMV识别到红色,find_cir = 1,若未识别到则为2;
		send_mission_to_open(X) X:1为红色 2为绿色 3为蓝色				*/
		case 0:		//识别到红色
		send_mission_to_open(1);//发送标志位让OPENMV识别红色
		delay_ms(50);
		/* ---------------------------- 首先识别到红色,跳入下个标志位,等待红色离开 --------------------------- */
		if(find_cir == 1)
		{
			openmv_tiaozheng_flag = 1;
		}
		break;
		/* ------------------------ 然后等待红色离开,红色离开后开始跳入下个标志位等待绿色进入视野 ----------------------- */
		case 1:		//识别到红色离开也就是识别到绿色(find_cir =  2是未识别到红色)
		delay_ms(50);
		if(find_cir == 2)
		{
			openmv_tiaozheng_flag = 2;
		}
		break;
		/* ---------------------------- 绿色进入视野开始识别绿色并且追踪 ---------------------------- */
		case 2:		//识别绿色,开始追踪绿色,确定中心点
		catching = 0;
		send_mission_to_open(2);//开始追踪绿色
		if(find_cir == 1)
		{
			OPENMV_YUANPANPID_CTRL();//车辆调整	
			if(TIM7_100ms>25)//调整两秒
			{	
				TIM7_100ms = 0;
				TIM_Cmd(TIM7, DISABLE);	
				openmv_tiaozheng_flag = 3;
				send_mission_to_open(7);/等待更新任务
			}
			else 		TIM_Cmd(TIM7, ENABLE);			
		}
		/* ---------------------- 若一直未识别到则一直关闭定时器等待识别两秒后跳入下个标志位 --------------------- */
		else if(find_cir == 2) 
			TIM_Cmd(TIM7, DISABLE);	
		break;
		/* ----------------------- 追踪完成,发送7则是不识别任何东西,等待下次更新任务 ----------------------- */
		case 3:		
		catching = 1;//开始抓取标志位,抓取物块
		send_mission_to_open(7);/等待更新任务
		find_cir =2;//手动更新为2,防止出现意外。
		if(TIM7_1000ms>3)//等待三秒后进入下个任务,此为防止任务过快出现BUG
		{
				openmv_tiaozheng_flag = 100;//重置到最开头便于下次重新调用此函数
				clear_OPENMV_PID();//清空PID防止下次调用PID时有数值残留导致运行错误
				clear_Encoder_PID();//清空PID防止下次调用PID时有数值残留导致运行错误
				/* --------------------- first_end标志位:第一圈跑完的话此标志位置1,否则置0 -------------------- */
				if(first_end == 0)// 如果第一圈未跑完,则进行第一圈的抓取任务
				quanju_mission_zt = 101;
				else			 // 如果第一圈跑完了,则进行第二圈的抓取任务
				quanju_mission_zt_second = 101;
				TIM_Cmd(TIM7, DISABLE);		TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
				TIM7_1000ms = 0;
				TIM7_100ms = 0;
		}
		else 		TIM_Cmd(TIM7, ENABLE);

		break;		
		}
 }

调整好距离后,就是识别-抓取,识别-抓取。

int catch_yuanpan_finish;//catch_yuanpan_finish是抓取任务结束后置0,所以正在抓取中则置1 ;
void catch_yuanpan(void)
{
	static int yuanpan_flag = 0;
	switch(yuanpan_flag)
	{
		case 0 :
		round_catch_high = 1;//圆盘抓取的点是距离地面高的位置,所以此标志位置1,方便电梯判断高度
		catching = 1;//正在抓取标志位置1 
		LobotSerialServoMove(ID1, 100,200);  //旋转底盘展开机械臂,使摄像头正对转盘上方,因为车子的垂直投影有大小限制,在行走的过程中,我们使机械臂处于收缩状态。
		delay_ms(50);

		Catch_SetCompare(20 );//爪子张开
		if(TIM6_1000ms>2)
		{
			
			clear_Encoder_PID(); //到达转盘清除编码器计数
			TIM6_1000ms = 0;
			TIM_Cmd(TIM6, DISABLE);
			yuanpan_flag = 1;
		}		
			else 			
			{
				TIM_Cmd(TIM6, ENABLE);	
				send_mission_to_open(mission_1);//识别1号的物料颜色				
			}
		break;		
/********************识别第一种 *********************/		
		case 1 :
		catching = 1;
		catch_yuanpan_finish = 0;//catch_yuanpan_finish是抓取任务结束后置0,所以正在抓取中则置1 ;
		send_mission_to_open(mission_1);//识别1号物料
		ZHUAZI_middle();//爪子下降到旋转圆盘的高度
		Catch_SetCompare(20 );//爪子张开
		if(find_cir ==1 )//识别到对应颜色200ms以上则跳入下个标志位进行抓取
		{
			if(TIM6_100ms>2)
			{
				TIM6_100ms = 0;
				TIM_Cmd(TIM6, DISABLE);
				yuanpan_flag = 2;
			}
			else 				TIM_Cmd(TIM6, ENABLE);			
		}
		else if(find_cir == 2)//没识别到则一直等待识别
		{
			TIM6_100ms = 0;
			TIM_Cmd(TIM6, DISABLE);
		}
			;
		break;
		case 2 :	//开始抓取物料
		catch_to_car(mission_1);//放置到车上物料盘
		if(mission_finish ==1)
		{
			yuanpan_flag = 3;
			send_mission_to_open(mission_2);//识别2号物料
		};
		break;	
/********************识别第一种 *********************/	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值