帮我用pyqt写一个程序,功能是发订单以及交互,适配底层agv系统;具体需求
1.初始化的时候,加载一下pg数据库的layer1_agv.agv表,根据字段agv_dispatch_type分车型,得到每个车型有几个车,agv表的结构是CREATE TABLE IF NOT EXISTS layer1_agv.agv
(
id integer NOT NULL DEFAULT nextval('agv_id_seq'::regclass),
agv_type_id integer NOT NULL,
agv_name character varying(20) COLLATE pg_catalog."default" NOT NULL,
mac_address macaddr,
ip_address inet,
agv_shell_port integer,
agv_control_port integer,
created_user character varying(200) COLLATE pg_catalog."default",
created_timestamp timestamp with time zone DEFAULT now(),
last_updated_user character varying(200) COLLATE pg_catalog."default",
last_updated_timestamp timestamp with time zone DEFAULT now(),
agv_layout_id integer,
agv_simulation_flg integer,
jess_port integer,
max_traffic_distance double precision,
vehicle_report_port integer,
agv_dispatch_type integer,
CONSTRAINT agv_pk PRIMARY KEY (id),
CONSTRAINT agv_uk01 UNIQUE (agv_name),
CONSTRAINT agv_uk02 UNIQUE (mac_address),
CONSTRAINT agv_fk01 FOREIGN KEY (agv_type_id)
REFERENCES layer1_agv.agv_type (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
);
2.加载layer2_pallet.location表,根据agv_type字段分类,得到每个agv_type下面的location内容,location表的字段如下CREATE TABLE IF NOT EXISTS layer2_pallet.location
(
id integer NOT NULL DEFAULT nextval('location_id_seq'::regclass),
location_type_id integer,
location_name character varying(200) COLLATE pg_catalog."default" NOT NULL,
layout_dock_id integer,
shelf_layer integer,
active boolean NOT NULL DEFAULT true,
physical_label character varying(200) COLLATE pg_catalog."default",
posture_type_id integer,
created_user character varying(200) COLLATE pg_catalog."default",
created_timestamp timestamp with time zone DEFAULT now(),
last_updated_user character varying(200) COLLATE pg_catalog."default",
last_updated_timestamp timestamp with time zone DEFAULT now(),
operation_parameter_fetch integer,
operation_parameter_put integer,
center_pos_x double precision,
center_pos_y double precision,
length double precision,
width double precision,
height double precision,
is_leaf boolean,
priority double precision,
exit_dock_id integer,
can_put boolean DEFAULT true,
is_booked boolean DEFAULT false,
parameter_json jsonb,
rest_active boolean NOT NULL DEFAULT true,
agv_type character varying(200) COLLATE pg_catalog."default",
angle double precision,
CONSTRAINT location_pk PRIMARY KEY (id),
CONSTRAINT location_uk UNIQUE (location_name),
CONSTRAINT location_fk01 FOREIGN KEY (location_type_id)
REFERENCES layer2_pallet.location_type (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT location_fk02 FOREIGN KEY (posture_type_id)
REFERENCES layer2_pallet.posture_type (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
3.获取到内容后,有一个map来匹配agv表的agv_dispatch_type和location表的agv_type,这个预留,我来写就可以了
4.发单程序逻辑,每个车型一个携程去发单,比如说1车型,他下面有几个正常状态的车,就确保该车型的订单数量是否达到车数,没达到就创建,达到就不创建,查询正常状态的车是从layer1_agv.agv_state表里查询,判断agv_management_status_id是7或者9代表正常,这个正常的车数是动态更新的;查询当前活跃订单是从数据库layer4_1_om."order"表里面查询,判断status字段是在waiting/active的情况下是活跃订单
5.现在开始分任务的参数,其中A8车和Fork车都很简单,是点到点,就是一个起点location到终点location,所以要从location表里面分类成起点和终点即可,但是尽量一次循环内,把所有的站台都跑到
6.现在开始下发A8车和Fork车的任务,这个比较简单,是点到点,就是一个起点location到终点location,按照第5点的分类来下发,下发的url是http://127.0.0.1/api/om/order/,post请求,参数可以参考如下{
"order_name": "No101",
"priority": 1,
"dead_line": "2024-1-30 15:15:30",
"ts_name": "p2p",
"parameters": "{\"src\":\"Work16\",\"dst\":\"Work28\",\"carrier_type_id\":-99,\"agv_type\":"1,2,3,4,"}",
"created_user": "WCS"
},其中src填起点,dst填终点location,其余参数固定就可以了,返回的参数是{
"app_name": "Guozi client",
"version": "1.0.0",
"code": 0,
"msg": "success",
"data": [
{
"in_order_id": 1 //订单id,唯一,创建任务时反馈给用户
}
]
},其中的in_order_id作为这个订单的状态反馈的标识字段;
7.新增接口用于任务状态反馈,url是当前程序的ip端口加上/orderStatusReport/,判断返回的orderStatus是finish代表orderID这个订单完成啦。收到信息的参数参考如下是{
"orderID": 2,
"orderName": "order_name",
"orderStatus": "source_finish",
"agvIDList": "1",
"priority": 2,
"currentDes": "work1",
"currentCmd": "poll_task_finished 190",
"errorCode": 0,
"extraInfo1": "",
"extraInfo2": "",
"deadLine": "2023-12-28 13: 46: 22",
"createdTime": "2024-01-07 10: 03: 41",
"createdUser": "admin",
"StatusChangeTime": "2024-01-07 10: 08: 16"
}
8.现在开始做辊道车的任务,这个比较复杂,因为辊道车是两层,每层两个口,所以就有多种动作类型,比如我们以车头朝向为例上层的位置是2A,2B,下层的位置是1A,1B,A是车头侧,下发订单的url和上面的一样,但是下发的内容不一样,示例1:请求示例body 去库位Work8取一个货物到上层2B储位,参数是{
"order_name": "No101",
"priority": 1,
"dead_line": "2024-1-30 15:15:30",
"ts_name": "roller_ts_ly",
"parameters": "{\"dst\": \"Work8\",\"posture\": \"tail\",\"agv_id\": \"1\",\"is_lock\": \"false\",\"is_large_size\":\"true\",\"actions\": \"[{\\\"cell_name\\\": \\\"2B\\\",\\\"type\\\": \\\"fetch\\\",\\\"seq\\\": 1}]\"}",
"created_user": "WCS"
};示例2:请求示例body 先后取两个货物上层2B、2A储位,参数是{
"order_name": "No101",
"priority": 1,
"dead_line": "2024-1-30 15:15:30",
"ts_name": "roller_ts_ly",
"parameters": "{\"dst\":\"Work16\",\"posture\":\"head\",\"agv_id\":\"1\",\"is_lock\":\"true\",\"is_large_size\":\"true\",\"actions\":\"[{\\\"cell_name\\\":\\\"2B\\\",\\\"type\\\":\\\"fetch\\\",\\\"seq\\\":1},{\\\"cell_name\\\":\\\"2A\\\",\\\"type\\\":\\\"fetch\\\",\\\"seq\\\":2}]\"
}",
"created_user": "WCS"
};示例3:请求示例body 下层1A储位卸一个货物,参数是{
"order_name": "No101",
"priority": 1,
"dead_line": "2024-1-30 15:15:30",
"ts_name": "roller_ts_ly",
"parameters": "{\"dst\":\"Work16\",\"posture\":\"head\",\"agv_id\":\"1\",\"is_lock\":\"true\",\"is_large_size\":\"true\",\"actions\":\"[{\\\"cell_name\\\":\\\"1A\\\",\\\"type\\\":\\\"put\\\",\\\"seq\\\":1}]\"
}",
"created_user": "WCS"
};示例4:请求示例body 下层1A、1B储位先后卸两个货物,参数是{
"order_name": "No101",
"priority": 1,
"dead_line": "2024-1-30 15:15:30",
"ts_name": "roller_p",
"parameters": "{\"dst\":\"Work16\",\"posture\":\"head\",\"agv_id\":\"1\",\"is_lock\":\"true\",\"is_large_size\":\"true\",\"actions\":[{\"cell_name\":\"1A\",\"type\":\"put\",\"seq\":1},{\"cell_name\":\"1B\",\"type\":\"put\",\"seq\":2}]
}",
"created_user": "WCS"
},示例5:请求示例body 上层2A卸一个货物,同时下层1B取一个货物,参数是{
"order_name": "No101",
"priority": 1,
"dead_line": "2024-1-30 15:15:30",
"ts_name": "roller_p",
"parameters": "{\"dst\":\"Work16\",\"posture\":\"head\",\"agv_id\":\"1,2,3\",\"is_lock\":\"true\",\"is_large_size\":\"true\",\"actions\":\"[{\\\"cell_name\\\":\\\"2A\\\",\\\"type\\\":\\\"put\\\",\\\"seq\\\":1},{\\\"cell_name\\\":\\\"1B\\\",\\\"type\\\":\\\"fetch\\\",\\\"seq\\\":1}]\"
}",
"created_user": "WCS"
}。示例如上,返回的参数和A8的一致;
9.辊道车第一个特殊点是,这个车可以先取一个货,再取一个货,最终一次性卸两个,也可以去一个站台取货+卸货同时做;
10.辊道车第二个特殊点是,is_lock字段和agv_id字段,is_lock字段,是比如我从work1取货到1A,这个车卸货之前,下发的订单不管是取货,还是卸货is_lock都是True,车号通过订单状态推送的agvIDList字段来获取,只会有一个车,所以我们辊道车的任务应该是第一个任务不指定车,第二个开始指定车(指定的是第一个车去接着取货/卸货)
11.辊道车要考虑到车头和车尾以及位置,不要出现1A取货后,卸货从2B来这样离谱的场景,以及车头1A取货后,又从车头取货到1B这样离谱的情况,考虑实际位置是否被阻挡
12.整体框架用fastapi,需要有pyqt界面,记录下发了哪些库位,当前完成的订单,每个订单从发出到完成的耗时
13.完整日志写到界面上,保证代码的茁壮和优雅
相信你,csdn,一次性帮我搞定!