TS的点与区域的写法

讲在前面

以下的TS中para_template变量是一个字典类型,我们需要获取字典中的值。该值也是个字典类型,我们要获取该字典中的值,这里统一使用的方法是self.src(self.该字典的键)。

本例下方使用的变量

有空库位(等价于该库位上没有托盘)
self.src # 起点
self.dst # 终点
self.unload_area/self.upload_area # 卸载区域
self.load_area # 装载区域
self.pallet_type # 托盘类型

while循环

除了p2p没有使用while循环,其他都有异常判断,等待下次获取正确的托盘或库位,故都使用了while循环,while循环使用continue结束本次循环,break结束循环。

四种TS的程序流程图

omi相关

只有调用写入日志的omi没有使用await;该omi是self.logger.info()
其余omi是

作用 omi名称 传入参数 返回值
获取取卸货的opt get_location_opt location_name/location_id (fetch_opt,put_opt)
下发取卸货任务 goto_location_act destination/destination_id,put_opt,FollowTask(后置任务,可选flase/true),agv_type,AGV(指定AGV去做任务,一般为None),PreTask(前置任务id,无可写None) task_id

p2p(点到点)

用到的OMI接口

# 获取目标名的opt
get_location_opt(传入目标名/目标id)==>返回元组(fetch_opt,put_opt)
# 根据传入的是fetch_opt还是put_opt确定是取卸货任务
goto_location_act(传入目标名/目标id,put_opt,FollowTask(后置任务,可选flase/true),agv_type,AGV(指定AGV
去做任务,一般为None),PreTask(前置任务id,无可写None))==>返回task_id(int)
# 更新自定义订单状态
update_order_status()

编写代码出现的报错坑

agv_type写成了self.agv_type
get_location_opt写成了get_loaction_opt
goto_location_act写成了get_location_act

实现的逻辑

获取取货opt

src_fetch_opt,src_put_opt =await self.get_location_opt(self.src)

下发取货任务

task_id = await self.get_location_act(self.src,src_fetch_opt,True,agv_type,None,None)

更新订单状态

await self.update_order_status('src_finish')

获取卸货opt

dst_fetch_opt,dst_put_opt = await self.get_loaction_opt(self.dst)

下发卸货任务

task_id = await self.get_location_act(self.dst,dst_put_opt,False,agv_type,None,task_id)

完整代码

src_fetch_opt,src_put_opt =await self.get_location_opt(self.src)
task_id = await self.goto_location_act(self.src,src_fetch_opt,True,agv_type,None,None)
# 更新状态
await self.update_order_status('src_finish')
# 卸货
dst_fetch_opt,dst_put_opt = await self.get_location_opt(self.dst)
task_id = await self.goto_location_act(self.dst,dst_put_opt,False,agv_type,None,task_id)
await self.update_order_status('dst_finish')

p2a(点到区域)

用到的OMI接口

获取目标位置的当前托盘name和托盘类型name:get_location_pallet_and_type(目标位置名/目标ID)==>[(current_pallet_name,current_pallet_type),]
设置目标托盘的类型:set_pallet_type(pallet_name,pallet_type)==> 无返回值
添加托盘:add_pallet(pallet_name,pallet_type) ==>返回个数字,小于0则为添加失败
添加托盘批次:set_pallet_batch_no(pallet_name,str(time.time()).replace(".", "0"))==>无返回值
设置目标托盘的位置(添加托盘到库位):set_pallet_location(pallet_name,目标位置名/目标ID)==>成功返回0,不成功返回小于0
查询库位是否有当前托盘类型的托盘位置并锁定:get_put_location_by_rule([self.unload_area],self.pallet_type)
更新更新自定义订单状态:self.update_order_status
更新日志使用: self.logger.info

实现的逻辑

先进行异常情况判断,在进行正常的取卸货

1.判断起点是否有空托盘,无则新增,将托盘加到当前卸货库位

查询目标位置是否有托盘,返回元组类型的托盘信息

current_pallet_info = await self.get_location_pallet_and_type(self.src)

先判断托盘信息有是有效的,再设定托盘类型

if current_pallet_info != (None,None):
    # 从托盘信息中提取出托盘名,托盘类型
    current_pallet_name = current_pallet_info[0][0]
    current_pallet_type = current_pallet_info[0][1]
    # 在判断托盘类型是否相同(托盘类型这里可人为的传入),
    if current_pallet_type != self.pallet_type:
    # 设置托盘类型为我们人为给定的托盘
        await self.set_pallet_type(current_pallet_name,self.pallet_type)

再判断托盘类型是无效的,创建托盘

self.logger.info('current_pallet_info:{} is error,aleady create pallet_name'.format(current_pallet_info))
pallet_name = time.strftime('%Y%m%d%H%M%S',time.localtime())
# 添加托盘接口,返回个数字,小于0则创建托盘失败
ret = await self.add_pallet(pallet_name,self.pallet_type)    

若创建托盘失败,则更新订单,写入日志

if ret < 0:
    # 更新订单信息
    await self.update_order_status('pallet_name:{} add error '.format(pallet_name))    
    # 更新日志使用self.logger.info
    self.logger.info('current_pallet_name:{}  add pallet error!'.format(current_pallet_name))
    # 本次循环无托盘信息,跳过(有可能库位会锁)
    await self.ts_delay(5)

若创建托盘成功,设置托盘批次

# 添加创建成功的日志
self.logger.info('pallet_name:{} create success'.format(current_pallet_name))
# 添加托盘批次
await self.set_pallet_batch_no(pallet_name,str(time.time()).replace(".", "0"))

设置托盘到当前卸货库位,并判断是否设置成功

ret = await self.set_pallet_location(pallet_name,self.unload_area)
if ret < 0:
    # 更新订单信息
    await self.update_order_status('pallet_name:{} already add  {}'.format(pallet_name,self.unload_area))    
    # 更新日志使用self.logger.info
    self.logger.info('pallet_name:{} already add  {}'.format(pallet_name,self.unload_area))
    # 本次循环无托盘信息,跳过(有可能库位会锁)
    await self.ts_delay(5)
2.判断是否有空库位,进行正常的取卸货

查询目标位置是否有当前托盘类型的空托盘位置

dst_empty_location = await self.get_put_location_by_rule([self.unload_area],self.pallet_type)

判断:有则进行起点取货,终点卸货

if dst_empty_location != (None,None):
    await self.update_order_status('active')
    '''
    AGV执行任务的主要就是这四句
    '''
    # 起点取货
    task_id = await self.goto_location_load(self.src,True,agv_type,None,None)
    # 更新状态
    await self.update_order_status('source finish')
    # 终点卸货
    task_id = await self.goto_location_unload(dst_empty_location[0],True,agv_type,None,task_id)
    # 更新状态
    await self.update_order_status('source finish')

没有的话:循环等待下次(库位有可能会锁)

await self.ts_delay(5)
continue

a2a(区域到区域)

本文中区域等同于库位

OMI接口

查询取货有无托盘,有无空库位,并锁定(空库位代表该库位有托盘):get_fetch_locations_by_rule([self.load_area], self.pallet_type,["leaf_reverse"]# 默认按location ID逆序排列)==>src_full_location对象实际是(location_name, pallet_name)元组
取货(需要库管信息):goto_location_load(src_full_location[0], True, agv_type)==> int task_id 失败则结束订单
卸货(需要库管信息):goto_location_unload(dst_empty_location[0],True,agv_type,None,None(有前置任务则填task_id))
释放锁定的库位:release_location(src_full_location[0])==> 成功则返回0解除锁定;失败则返回1解除锁定失败(location不存在)
get_parent_by_type(dst_empty_location[0], parent_location_type(父节点的类型,手动指定))==>失败返回None,成功返回parent_location

实现的逻辑

查询有无托盘,有无空库位,并锁定

src_full_pallet = await self.get_fetch_locations_by_rule([self.load_area],self.pallet_type)
dst_empty_location = await self.get_fetch_locations_by_rule([self.upload_area],self.pallet_type)

有托盘,有空库位

if src_full_pallet != (None,None) and dst_empty_location != (None,None):
    # 起点取货
    task_id = await self.goto_location_load(src_full_pallet[0],True,agv_type)
    await self.update_order_status('load finish') 
    # 终点卸货
    task_id = await self.goto_location_load(dst_empty_location[0],False,agv_type,None,task_id)   
    await self.update_order_status('upload finish')

有托盘,无空库位(无空读起来很扭)

elif src_full_pallet != (None,None) and dst_empty_location == (None,None):
    # 注意:这里获取到了dst_empty_location虽然为None,但对于库位来说它的父对象巷道也锁到了
    ret = await self.release_location(src_full_pallet[0])
    parent_location = await self.get_parent_by_type(src_full_pallet[0],self.parent_location_type)
    ret = await self.release_location(src_full_pallet[0],parent_location)
    await self.update_order_status('No empty location ')
    await self.ts_delay(5)

无托盘,有空库位

elif src_full_pallet == (None,None) and dst_empty_location != (None,None):
    ret = await self.release_location(src_full_pallet[0])
    parent_location = await self.get_parent_by_type(dst_empty_location[0],self.parent_location_type)
    ret = await self.release_location(src_full_pallet[0],parent_location)
    await self.update_order_status('No empty pallet')
    await self.ts_delay(5)

a2p(区域到点)

OMI接口

查询区域是否有托盘/空库位,并锁定:get_fetch_locations_by_rule([self.load_area], self.pallet_type,["leaf_reverse"]# 默认按location ID逆序排列)==>src_full_location对象实际是(location_name, pallet_name)元组
取货(带库管信息):goto_location_load(src_full_location[0], True, agv_type)==> int task_id 失败则结束订单
卸货(带库管信息):goto_location_unload(dst,follow_task,agv_type, None, task_id)==> task_id   

具体实现的逻辑

查询区域是否有托盘,并锁定

src_full_pallet = await self.get_fetch_locations_by_rule([self.load_area],self.pallet_type)

有则进行取货卸货

if src_full_pallet != (None,None):
    task_id = await self.goto_location_load(src_full_pallet[0],True,agv_type)
    await self.update_order_status('source_finish')
    task_id = await self.goto_location_unload(self.dst,False,agv_type,None,task_id)
    await self.update_order_status('source_finish')

没有则循环在次等待

await self.update_order_status('no fit pallet')
await self.ts_delay(5)
posted @ 2022-03-11 10:38  索匣  阅读(264)  评论(0编辑  收藏  举报