123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- # 导入pymysql
- import pymysql as psql
- from retry import retry
- import message_pb2 as message
- import google.protobuf.text_format as tf
- import threading
- import datetime
- import uuid
- import math
- class CommandInfo:
- def __init__(self,type,table):
- self.type=type
- self.table=table
- class DBCommand():
- def __init__(self,ip,port,database,user,password):
- self.ip=ip
- self.port=port
- self.database=database
- self.user=user
- self.password=password
- self.lock=threading.Lock()
- self.conn=psql.connect(host=ip,
- port=port,
- database=database,
- charset="utf8",
- user=user,
- passwd=password)
- def push_command(self,cmd_table):
- #判断指令类型
- if self.table_type(cmd_table)=="park":
- ret_table=self.enqueue_parkcmd(cmd_table)
- elif self.table_type(cmd_table)=="pick":
- ret_table=self.enqueue_pickcmd(cmd_table)
- else:
- print(" 入队指令格式错误")
- return None
- return ret_table
- def enqueue_parkcmd(self,table):
- with self.lock:
- cmd=message.park_table()
- tf.Parse(table,cmd)
- self.conn.ping()
- self.conn.begin()
- cursor = self.conn.cursor()
- #检查车辆是否在库内
- SQL="select * from vehicle where car_number='%s'"%(cmd.car_number)
- exist_vehicle=cursor.execute(SQL)
- SQL="select * from command_queue where car_number='%s'"%(cmd.car_number)
- exist_command=cursor.execute(SQL)
- if exist_command>0 or exist_vehicle>0:
- ts=message.table_statu()
- ts.execute_statu=message.eError
- ts.statu_description="车辆 :%s 已在库内!"%(cmd.car_number)
- cmd.statu.CopyFrom(ts)
- self.conn.commit()
- cursor.close()
- return tf.MessageToString(cmd,as_utf8=True)
- #检查车位是否够
- elif cmd.entrance_measure_info.height<1.55:
- #小轿车, 总车位数-队列等待数>0即可
- SQL="select * from space where car_number IS NULL and unit=%d and statu=0"%(cmd.unit_id)
- idle_space_count=cursor.execute(SQL)
- SQL="select * from command_queue where unit=%d and statu=0 and type=1"%(cmd.unit_id)
- wait_park_count=cursor.execute(SQL)
- if not idle_space_count-wait_park_count>0:
- ts=message.table_statu()
- ts.execute_statu=message.eError
- ts.statu_description="没有空余车位,车牌号:%s 高度:%.3fm!"%(cmd.car_number,cmd.entrance_measure_info.height)
- cmd.statu.CopyFrom(ts)
- self.conn.commit()
- cursor.close()
- return tf.MessageToString(cmd,as_utf8=True)
- elif cmd.entrance_measure_info.height<1.75:
- #suv ,空闲suv车位-队列suv 在(队列空闲轿车-空闲轿车位)>0时,需要减去这个
- SQL="select * from space where car_number IS NULL and unit=%d and height>1.55 and height<=1.75 and statu=0"%(cmd.unit_id)
- suv_idl_count=cursor.execute(SQL) #空闲suv车位数
- SQL="select * from space where car_number IS NULL and unit=%d and height<=1.55 and statu=0"%(cmd.unit_id)
- mini_idle_count=cursor.execute(SQL) #轿车位数
- SQL="select * from command_queue where unit=%d and statu=0 and type=1"%(cmd.unit_id)
- cursor.execute(SQL)
- queue_cmd=cursor.fetchall() #所有等待指令
- queue_car_count=0 #队列轿车指令计数
- for qc in queue_cmd:
- info=message.measure_info()
- tf.Parse(qc[7],info)
- if info.height<=1.55: #队列轿车停车指令
- queue_car_count=queue_car_count+1
- queue_suv_count=len(queue_cmd)-queue_car_count
- space_scarcity=0
- if mini_idle_count<queue_car_count:
- space_scarcity=queue_car_count-mini_idle_count
- if not (suv_idl_count-queue_suv_count-space_scarcity)>0:
- ts=message.table_statu()
- ts.execute_statu=message.eError
- ts.statu_description="没有SUV车位,车牌号:%s,高度:%.3fm!"%(cmd.car_number,cmd.entrance_measure_info.height)
- cmd.statu.CopyFrom(ts)
- self.conn.commit()
- cursor.close()
- return tf.MessageToString(cmd,as_utf8=True)
- elif cmd.entrance_measure_info.height<2.0:
- SQL = "select * from space where car_number IS NULL and unit=%d and height>1.75 and height<=2.0 and statu=0" % (cmd.unit_id)
- big_idl_count = cursor.execute(SQL) # 空闲 big 车位数
- SQL = "select * from space where car_number IS NULL and unit=%d and height>1.55 and height<=1.75 and statu=0" % (cmd.unit_id)
- suv_idle_count = cursor.execute(SQL) # suv位数
- SQL = "select * from space where car_number IS NULL and unit=%d and height<=1.55 and statu=0" % (cmd.unit_id)
- small_idle_count = cursor.execute(SQL) # 轿车位数
- if big_idl_count>=1:
- cmd_small_count=0
- cmd_suv_count=0
- cmd_big_count=0
- SQL = "select * from command_queue where unit=%d and statu=0 and type=1" % (cmd.unit_id)
- cursor.execute(SQL)
- queue_cmd = cursor.fetchall() # 所有等待指令
- for qc in queue_cmd:
- info = message.measure_info()
- tf.Parse(qc[7], info)
- if info.height <1.55: # 队列轿车停车指令
- cmd_small_count = cmd_small_count + 1
- elif info.height<1.75:
- cmd_suv_count=cmd_suv_count+1
- elif info.height<2.0:
- cmd_big_count=cmd_big_count+1
- else:
- pass
- suv_space_scarcity = 0
- if small_idle_count < cmd_small_count:
- suv_space_scarcity = cmd_small_count - small_idle_count
- suv_idle_count=suv_idle_count-suv_space_scarcity
- if cmd_suv_count-suv_idle_count>0:
- big_idl_count=big_idl_count-(cmd_suv_count-suv_idle_count)
- if big_idl_count<0:
- ts = message.table_statu()
- ts.execute_statu = message.eError
- ts.statu_description = "没有SUV车位,车牌号:%s,高度:%.3fm!" % (
- cmd.car_number, cmd.entrance_measure_info.height)
- cmd.statu.CopyFrom(ts)
- self.conn.commit()
- cursor.close()
- return tf.MessageToString(cmd, as_utf8=True)
- else:
- ts = message.table_statu()
- ts.execute_statu = message.eError
- ts.statu_description = "没有SUV车位,车牌号:%s,高度:%.3fm!" % (
- cmd.car_number, cmd.entrance_measure_info.height)
- cmd.statu.CopyFrom(ts)
- self.conn.commit()
- cursor.close()
- return tf.MessageToString(cmd, as_utf8=True)
- else:
- ts = message.table_statu()
- ts.execute_statu = message.eError
- ts.statu_description = "车辆超高,车牌号:%s,高度:%.3fm!" % (
- cmd.car_number, cmd.entrance_measure_info.height)
- cmd.statu.CopyFrom(ts)
- self.conn.commit()
- cursor.close()
- return tf.MessageToString(cmd, as_utf8=True)
- #指令允许入队,填写唯一码
- if not cmd.statu.execute_statu==message.eError:
- uid=str(uuid.uuid1())
- cmd.primary_key=uid
- #查询队列指令以及最后一次指令编号及时间
- cursor.execute("select * from command_queue,queue_number_data FOR UPDATE") #锁表
- SQL="select * from command_queue where unit=%d and statu=0"%(cmd.unit_id)
- cursor.execute(SQL)
- cmd_queue=cursor.fetchall()
- queue_id=0
- #计算当前指令编号
- if len(cmd_queue)>0:
- SQL="select * from queue_number_data where unit=%d"%cmd.unit_id
- cursor.execute(SQL)
- record=cursor.fetchall()
- last_num=0
- last_time=datetime.datetime.now()
- if len(record)==1:
- last_num=record[0][1]
- last_time=record[0][2]
- elif len(record)==0:
- SQL="insert into queue_number_data values(%d,0,NULL)"%(cmd.unit_id)
- cursor.execute(SQL)
- diff=datetime.datetime.now()-last_time
- time_mns=diff.total_seconds()/60
- queue_id=int(last_num+1+ time_mns*1)
- #停车入队前,按照库内轴距更新测量轴距值 --------------------------------------------
- database_wheelbase=self.get_wheelbase(cursor,cmd.car_number)
- new_wheelbase=cmd.entrance_measure_info.wheelbase
- if database_wheelbase is not None:
- [wheelbase,delta]=database_wheelbase
- entrance_wheelbase=cmd.entrance_measure_info.wheelbase
- if abs(entrance_wheelbase-wheelbase)>0.1: #与入口测量偏差过大,不更新
- print("车辆:%s 测量轴距与数据库相差太大(测量:%f 数据库:%f),不做融合,以测量为准"%(cmd.car_number,entrance_wheelbase,wheelbase))
- else:
- sum=(delta*delta)+0.05*0.05
- new_wheelbase=entrance_wheelbase*delta*delta/sum+wheelbase*(0.05*0.05)/sum
- print("车辆:%s 停车更新轴距:%f ,测量:%f,数据库:%f"%(cmd.car_number,new_wheelbase,entrance_wheelbase,wheelbase))
- new_measure_info=message.measure_info()
- new_measure_info.CopyFrom(cmd.entrance_measure_info)
- new_measure_info.wheelbase=new_wheelbase
- cmd.entrance_measure_info.CopyFrom(new_measure_info)
- else:
- print("车辆:%s 不存在数据库轴距,使用测量轴距:%f"%(cmd.car_number,cmd.entrance_measure_info.wheelbase))
- #-----------------------------------
- SQL="insert into command_queue values('%s','%s',%d,%d,1,0,NULL,'%s', %d , NULL)"%(
- cmd.car_number,cmd.primary_key,cmd.unit_id,queue_id
- ,tf.MessageToString(cmd.entrance_measure_info,as_utf8=True), cmd.terminal_id )
- cursor.execute(SQL)
- #更新指令时间表,
- dt=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
- SQL="update queue_number_data set last_number=%d,input_time=str_to_date('%s','%%Y-%%m-%%d %%H:%%i:%%S') where unit=%d"%(queue_id,dt,cmd.unit_id)
- cursor.execute(SQL)
- self.conn.commit()
- cursor.close()
- return tf.MessageToString(cmd,as_utf8=True)
- def enqueue_pickcmd(self,table):
- with self.lock:
- cmd=message.pick_table()
- tf.Parse(table,cmd)
- #检查车辆是否在车位表,查找对应车位,找到即入队
- self.conn.ping()
- self.conn.begin()
- cursor = self.conn.cursor()
- SQL="select * from vehicle where primary_key='%s'"%(cmd.primary_key)
- cursor.execute(SQL)
- car_info=cursor.fetchall()
- if not len(car_info)>=1:
- ts=message.table_statu()
- ts.execute_statu=message.eError
- ts.statu_description="车辆信息不存在!"
- cmd.statu.CopyFrom(ts)
- else:
- SQL="select * from command_queue where primary_key='%s'"%(cmd.primary_key)
- num=cursor.execute(SQL)
- if num>0: #取车指令在对哦中,不能执行
- ts=message.table_statu()
- ts.execute_statu=message.eError
- ts.statu_description="指令正在执行中,请稍等!"
- cmd.statu.CopyFrom(ts)
- else:
- car_number=car_info[0][0]
- cmd.car_number=car_number
- #查询车位
- SQL="select * from space where car_number='%s'"%(car_number)
- cursor.execute(SQL)
- space=cursor.fetchall()
- #找不到,将指令表单状态修改为error
- if not len(space)==1:
- ts=message.table_statu()
- ts.execute_statu=message.eError
- ts.statu_description="没有找到车辆信息,请联系管理员!"
- cmd.statu.CopyFrom(ts)
- else:
- #查询到单元号,给指令表单单元号赋值
- unit_id=space[0][5]
- cmd.unit_id=unit_id
- ts = message.table_statu()
- ts.execute_statu=message.eNormal
- if unit_id == 1:
- ch = "A"
- elif unit_id == 2:
- ch = "B"
- elif unit_id == 3:
- ch = "C"
- ts.statu_description="%s 取车成功,请前往%s单元出口取车!"%(car_number,ch)
- cmd.statu.CopyFrom(ts)
-
- #给指令表单车位信息赋值
- space_info=message.parkspace_info()
- space_info.id=space[0][0]
- space_info.unit_id=unit_id
- space_info.floor=space[0][1]
- space_info.room_id=space[0][2]
- cmd.actually_space_info.CopyFrom(space_info)
- #赋值真实测量信息
- measure_info=message.measure_info()
- tf.Parse(car_info[0][2],measure_info)
- cmd.actually_measure_info.CopyFrom(measure_info)
- #指令入库
- cursor.execute("select * from command_queue,queue_number_data FOR UPDATE") #锁表
- SQL="select * from command_queue where unit=%d and statu=0"%(unit_id)
- cursor.execute(SQL)
- cmd_queue=cursor.fetchall()
- queue_id=0
- if len(cmd_queue)>0:
- SQL="select * from queue_number_data where unit=%d"%unit_id
- cursor.execute(SQL)
- record=cursor.fetchall()
- last_num=0
- last_time=datetime.datetime.now()
- if len(record)==1:
- last_num=record[0][1]
- last_time=record[0][2]
- elif len(record)==0:
- SQL="insert into queue_number_data values(%d,0,NULL)"%(cmd.unit_id)
- cursor.execute(SQL)
- diff=datetime.datetime.now()-last_time
- time_mns=diff.total_seconds()/60
- queue_id=int(last_num+1+ time_mns*1)
- SQL="insert into command_queue values('%s','%s',%d,%d,2,0,'%s','%s',NULL, NULL)"%(
- cmd.car_number,cmd.primary_key,unit_id,queue_id,tf.MessageToString(cmd.actually_space_info,as_utf8=True)
- ,tf.MessageToString(cmd.actually_measure_info,as_utf8=True))
- cursor.execute(SQL)
- #更新指令时间表,
- dt=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
- SQL="update queue_number_data set last_number=%d,input_time=str_to_date('%s','%%Y-%%m-%%d %%H:%%i:%%S') where unit=%d"%(queue_id,dt,unit_id)
- cursor.execute(SQL)
- #取车指令入队完成,记录轴距信息
- self.update_wheelbase(cursor,cmd.car_number)
- self.conn.commit()
- cursor.close()
- return tf.MessageToString(cmd,as_utf8=True)
- def update_wheelbase(self,cursor,car_number):
- #取车指令入队成功,此处将车辆夹持杆轴距偏差按照 delta=0.03 更新 ----------------------------
- #获取车辆表中的轴距信息
- SQL="select actually_measure_info,plc_measure_info from vehicle where car_number='%s'"%car_number
- cursor.execute(SQL)
- records=cursor.fetchall()
- act_info=message.measure_info() #入口测量数据
- plc_info=message.measure_info() #plc反馈数据(夹持杆雷达)
- clamp_wheelbase=None
- if len(records)==1: #找到记录
- if records[0][0] is not None and records[0][1] is not None:
- tf.Parse(records[0][0],act_info)
- tf.Parse(records[0][1],plc_info)
- if abs(act_info.wheelbase-plc_info.wheelbase)<0.05: #入口数据与夹持数据相近,可靠,
- clamp_wheelbase=plc_info.wheelbase
- #夹持数据存在,且可靠数据,存库,
- if(clamp_wheelbase is not None):
- SQL="select * from car_parameter where car_number='%s'"%car_number
- cursor.execute(SQL)
- records=cursor.fetchall()
- update_wheelbase=clamp_wheelbase
- update_delta=0.03
- SQL="insert into car_parameter values('%s',%f,%f,%f,0.03)"%(car_number,update_wheelbase,update_delta,plc_info.width)
- if len(records)==1:#有历史数据
- wheel_base=float(records[0][1])
- wheel_base_delta=float(records[0][2])
- if abs(clamp_wheelbase-wheel_base)>0.05: #可能存在改装或者换牌,重置delta
- print("车辆:%s 可能存在换牌或者改装,重置轴距信息"%(car_number))
- else: #计算新值
- dcdc=update_delta*update_delta
- dd=wheel_base_delta*wheel_base_delta
- update_wheelbase=clamp_wheelbase*dd/(dcdc+dd)+wheel_base*dcdc/(dd+dcdc)
- update_delta=math.sqrt(dcdc*dd/(dcdc+dd))
- print("车辆:%s 更新数据库轴距:%.5f,标准差:%.5f"%(car_number,update_wheelbase,update_delta))
- SQL="update car_parameter set wheelbase=%f,var_wheelbase=%f where car_number='%s'"%(update_wheelbase,update_delta,car_number)
- else:
- print("新车:%s 第一次光临,存入轴距:%f"%(car_number,update_wheelbase))
- cursor.execute(SQL)
- def get_wheelbase(self,cursor,car_number):
- SQL="select * from car_parameter where car_number='%s'"%(car_number)
- cursor.execute(SQL)
- records=cursor.fetchall()
- if len(records)==1:
- wheelbase=float(records[0][1])
- delta=float(records[0][2])
- return [wheelbase,delta]
- else:
- return None
- @staticmethod
- def table_type(table):
- if table.find("entrance_measure_info")>=0:
- return "park"
- elif table.find("primary_key")>=0:
- return "pick"
|