def __init__(self, IP, AIPort, scenario_name, simulate_compression): self.control_noise = True self.SERVER_PLAT = "linux" self.SERVER_IP = IP self.SERVER_PORT = AIPort self.connect_mode = 1 self.DURATION_INTERVAL = etc.DURATION_INTERVAL self.simulate_compression = simulate_compression self.scenario_name = scenario_name self.mozi_service = MoziService(IP, AIPort, self.scenario_name, connect_mode=self.connect_mode) self.action_space = 4 self.action_max = 1 self.element_item_count = 7 self.observation_space = 7 * 2 self.last_situation_time = None self.red_unit_list = None self.blue_unit_list = None self.observation = None self.red_side_name = "红方" self.blue_side_name = "蓝方"
def connect_mozi_server(self, websocket_Ip, websocket_port): """ 连接墨子服务器 param : websocket_server 要连接的服务器的ip websocket_port 要连接的服务器的端口 :return: """ pylog.info("connect_mozi_server") if self.connect_mode == 1: self.mozi_service = MoziService(websocket_Ip, websocket_port, self.scenario_name) return True # server_address = r"ws://%s:%d/websocket" % ('60.205.207.206', 9998) server_address = r"ws://%s:%d/websocket" % (websocket_Ip, websocket_port) pylog.info(server_address) for i in range(10): try: self.websocket_connect = create_connection(server_address) break except: pylog.info("can not connect to %s." % server_address) time.sleep(2) self.websocket_connect = None # if self.websocket_connect is None: pylog.warning("Interrupted, can not connect to %s." % server_address) return False # self.websocket_connect.send("{\"RequestType\":\"StartServer\"}") result = self.websocket_connect.recv() print("connect server result:%s" % result) jsons = json.loads(result) self.ai_server = jsons['IP'] self.ai_port = jsons['AIPort'] self.mozi_task = MoziService(self.server_ip, self.aiPort, self.scenario_name) return True
class MoziEnv(): def __init__(self, IP, AIPort, scenario_name, simulate_compression): self.control_noise = True self.SERVER_PLAT = "linux" self.SERVER_IP = IP self.SERVER_PORT = AIPort self.connect_mode = 1 self.DURATION_INTERVAL = etc.DURATION_INTERVAL self.simulate_compression = simulate_compression self.scenario_name = scenario_name self.mozi_service = MoziService(IP, AIPort, self.scenario_name, connect_mode=self.connect_mode) self.action_space = 2 self.action_max = 1 self.observation_space = 3 self.last_situation_time = None self.red_unit_list = None self.blue_unit_list = None self.observation = None self.red_side_name = "美国海军" self.blue_side_name = "俄罗斯海军" def _init_red_unit_list(self): side_name = self.red_side_name ret_lt = [] side_guid = get_side_guid_from_side_name( side_name, self.mozi_service.all_info_dict) side_dic = get_a_side_dic(side_guid, self.mozi_service.all_info_dict) aircraft_list_dic = get_units_from_side( side_guid, "CAircraft", self.mozi_service.all_info_dict) for key in aircraft_list_dic: ret_lt.append(key) return ret_lt def _init_blue_unit_list(self): side_name = self.blue_side_name ret_lt = [] side_guid = get_side_guid_from_side_name( side_name, self.mozi_service.all_info_dict) submarine_list_dic = get_units_from_side( side_guid, "CSubmarine", self.mozi_service.all_info_dict) return ret_lt def _init_unit_list(self): self.red_unit_list = self._init_red_unit_list() self.blue_unit_list = self._init_blue_unit_list() def _get_a_side_observation(self, unit_list): obs_lt = [] for key in unit_list: unit = self.mozi_service.all_info_dict.get(key, "") if unit: obs_lt.append(unit["dLongitude"]) obs_lt.append(unit["dLatitude"]) obs_lt.append(unit["fCurrentHeading"]) else: pylog.info("unit do not exist") obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) return obs_lt def _get_blue_observation(self): unit_list = self.blue_unit_list obs_lt = self._get_a_side_observation(unit_list) return obs_lt def _get_red_observation(self): unit_list = self.red_unit_list obs_lt = self._get_a_side_observation(unit_list) return obs_lt def _get_observation(self): red_obs_lt = self._get_red_observation() self.observation = red_obs_lt if self._check_aircraft_exist(): if etc.TRANS_DATA: lt = [] lt.append(red_obs_lt[0] - etc.task_end_point["longitude"]) lt.append(red_obs_lt[1] - etc.task_end_point["latitude"]) lt.append(red_obs_lt[2] / 360) return lt return red_obs_lt def _set_duration_interval(self): self.mozi_service.mozi_task.sendAndRecv("Hs_OneTimeStop('Stop', %d)" % self.DURATION_INTERVAL) def _reset(self): ret = self.mozi_service.suspend_simulate() self.mozi_service.all_info_dict = {} self.scenario = self.mozi_service.load_scenario(plat=self.SERVER_PLAT) self._set_duration_interval() ret = self.mozi_service.set_run_mode() ret = self.mozi_service.set_simulate_compression( self.simulate_compression) ret = self.mozi_service.set_compression_mode(False) self._run_simulate() def _run_simulate(self): pylog.info("run simulation") return self.mozi_service.run_simulate() def _check_duration(self): update_situation_time = self.mozi_service.mozi_task.getCurrentTime() if self.last_situation_time != None: duration_time = float(update_situation_time) - float( self.last_situation_time) if int(duration_time) != self.DURATION_INTERVAL: pylog.error( "duration_time:%s is differet from etc.DURATION_INTERVAL:%s" % (duration_time, self.DURATION_INTERVAL)) self.last_situation_time = update_situation_time def _run_with_situation_data(self): self.mozi_service.update_situation(self.scenario) # self._check_duration() def _get_waypoint_heading(self, last_heading, action_value): current_heading = last_heading + action_value if current_heading < 0: current_heading += 360 if current_heading > 360: current_heading -= 360 return current_heading def _get_new_waypoint(self, heading, lat, lon, distance=20.0): dic = get_point_with_point_bearing_distance(lat, lon, heading, distance) return dic def _deal_point_data(self, waypoint): if self.control_noise: lon = str( float(waypoint["longitude"]) + random.random() / 10.0 - 0.05) lat = str( float(waypoint["latitude"]) + random.random() / 10.0 - 0.05) else: lon = str(waypoint["longitude"]), lat = str(waypoint["latitude"]), return lon, lat def _check_is_drop_sonobuoy(self, action_value): if action_value[1].item() > 0: return True return False def _get_aircraft_waypoint(self, action_value): obs = self.observation # pylog.info(obs) longitude = obs[0] latitude = obs[1] heading = obs[2] waypoint_heading = self._get_waypoint_heading( heading, action_value[0].item() * 90) waypoint = self._get_new_waypoint(waypoint_heading, latitude, longitude) distance = get_target_distance(latitude, longitude) return waypoint, distance def _execute_action(self, action_value): waypoint, distance = self._get_aircraft_waypoint(action_value) guid = self.red_unit_list[0] aircraft = self.mozi_service.get_entity(guid) if self._check_is_find_target(): target_guid = self._get_target_guid() # aircraft.autoattack_target(target_guid, self.mozi_service.mozi_task) aircraft.autoattack_target(target_guid) else: if distance < etc.target_radius: if self._check_is_drop_sonobuoy(action_value): # aircraft.drop_sonobuoy(self.red_side_name, "shallow", "active", self.mozi_service.mozi_task) aircraft.drop_sonobuoy(self.red_side_name, "shallow", "active") lon, lat = self._deal_point_data(waypoint) # aircraft.set_waypoint(self.red_side_name, guid, lon, lat, self.mozi_service.mozi_task) aircraft.set_waypoint(self.red_side_name, guid, lon, lat) def _check_done(self): if not self._check_aircraft_exist(): return True if not self._check_target_exist(): return True return False def _check_aircraft_exist(self): obs = self.observation for i in range(len(obs)): if obs[i] != 0.0: return True return False def _check_target_exist(self): if not check_is_exist_target(etc.target_name, self.mozi_service.all_info_dict): return False return True def _get_target_guid(self): target_name = etc.target_name target_guid = get_target_contact_guid_from_target_name( self.red_side_name, target_name, self.mozi_service.all_info_dict) return target_guid def _check_is_find_target(self): target_guid = self._get_target_guid() if target_guid: pylog.info("find target_guid:%s" % target_guid) return True return False def _get_distance_reward(self, action_value): obs = self.observation longitude = obs[0] latitude = obs[1] heading = obs[2] distance = get_target_distance(latitude, longitude) action_change_heading = action_value[0].item() * 90 reward = get_distance_reward(latitude, longitude, heading, action_change_heading) return reward, distance def _get_reward(self, action_value): reward = 0.0 distance_reward, distance = self._get_distance_reward(action_value) reward += distance_reward if distance < etc.target_radius: if self._check_is_drop_sonobuoy(action_value): # pylog.info("target area drop sonobuoy get 10.0 reward") reward += 10.0 else: if not self._check_aircraft_exist(): # pylog.info("aircraft is not exist get -100.0 reward") reward += -100.0 if self._check_is_find_target(): # pylog.info("find target get 10.0 reward") reward += 10.0 if not self._check_target_exist(): pylog.info("destroy target get 150.0 reward") reward += 150.0 return reward def reset(self): self._reset() self.mozi_service.init_situation(self.scenario) self._init_unit_list() obs = self._get_observation() return np.array(obs) def step(self, action): self._execute_action(action) self._run_with_situation_data() obs = self._get_observation() reward = self._get_reward(action) done = self._check_done() info = "" return np.array(obs), reward, done, info def connect_server(self): if not self.mozi_service.connect_mozi_server(self.SERVER_IP, self.SERVER_PORT): return False else: return True
class Environment(): ''' 环境 ''' def __init__(self, IP, AIPort, scenario_name, simulate_compression): self.server_ip = IP self.aiPort = AIPort self.scenario_name = scenario_name self.websocker_conn = None self.mozi_server = None self.scenario = None self.connect_mode = 1 self.num = 1 self.simulate_compression = simulate_compression #self.agent = CAgent() def step(self): ''' 步长 主要用途: 单步决策的方法 根据环境态势数据改变战场环境 ''' time.sleep(1/3) self.mozi_server.suspend_simulate() self.mozi_server.update_situation(self.scenario)#数据更新 self.redside.static_update()#数据组合 self.blueside.static_update() #写了一个my_step函数,用来执行动作 self.my_step(self.blueside) self.mozi_server.run_simulate() return self.scenario def reset(self): ''' 重置函数 主要用途: 加载想定, ''' self.mozi_server.suspend_simulate() self.mozi_server.load_scenario("linux") self.create_scenario() self.mozi_server.init_situation(self.scenario) self.redside = self.scenario.get_side_by_name('红方')# 获得红方的主对象 self.redside.static_construct() # 结构化平台返回数据,存入相应的实体属性中, self.blueside = self.scenario.get_side_by_name('蓝方')# 获得蓝方的主对象 self.blueside.static_construct() self.mozi_server.run_simulate() self.mozi_server.set_simulate_compression(4) #设定推演步长 #为了便于区分,定义了一个新的函数my_prepeo,以实例化的推演方对象作为参数输入,对推演前的任务进行设置 self.my_prepro(self.blueside) def create_scenario(self): ''' 建立一个想定对象 ''' self.scenario = CScenario(self.mozi_server) def connect_mozi_server(self, websocket_Ip, websocket_port): """ 连接墨子服务器 param : websocket_server 要连接的服务器的ip websocket_port 要连接的服务器的端口 :return: """ pylog.info("connect_mozi_server") if self.connect_mode == 1: self.mozi_server = MoziService(self.server_ip ,self.aiPort,self.scenario_name) return True # server_address = r"ws://%s:%d/websocket" % ('60.205.207.206', 9998) server_address = r"ws://%s:%d/websocket" % (websocket_Ip, websocket_port) pylog.info(server_address) for i in range(10): try: self.websocket_connect = create_connection(server_address) break except: pylog.info("can not connect to %s." % server_address) time.sleep(2) self.websocket_connect = None # if self.websocket_connect is None: pylog.warning("Interrupted, can not connect to %s." % server_address) return False # self.websocket_connect.send("{\"RequestType\":\"StartServer\"}") result = self.websocket_connect.recv() print("connect server result:%s" % result) jsons = json.loads(result) self.ai_server = jsons['IP'] self.ai_port = jsons['AIPort'] self.mozi_task = MoziService(self.server_ip ,self.aiPort,self.scenario_name) return True def start(self): ''' 开始函数 主要用途: 1.连接服务器端 2.设置决策时间 3.设置智能体决策想定是否暂停 ''' self.connect_mozi_server(self.server_ip,self.aiPort) self.mozi_server.set_run_mode() self.mozi_server.one_time_stop(10) def my_prepro(self,side): ''' 设置预先设定的任务 ''' #清空原本的想定任务 mission_keys=list(self.blueside.missions.keys()) for k in mission_keys: self.blueside.delete_mission(k) #记录信息,这部分是用来做条件判断 self.enm_miss=[] #设置推演方条令,对水面自由开火,对空自由开火,电磁管控开 doctrine=side.get_doctrine() doctrine.set_weapon_control_status_surface(0) doctrine.set_weapon_control_status_air(0) doctrine.set_em_control_status('Radar','Active') #设置武器打击距离 #51 doctrine.set_weapon_release_authority(weapon_dbid='51',target_type='1999', quantity_salvo='1', shooter_salvo='1',firing_range='45') doctrine.set_weapon_release_authority(weapon_dbid='51',target_type='2000', quantity_salvo='1', shooter_salvo='1',firing_range='45') doctrine.set_weapon_release_authority(weapon_dbid='51',target_type='2001', quantity_salvo='1', shooter_salvo='1',firing_range='45') #15 doctrine.set_weapon_release_authority(weapon_dbid='15',target_type='2200', quantity_salvo='1', shooter_salvo='1',firing_range='25') doctrine.set_weapon_release_authority(weapon_dbid='15',target_type='2201', quantity_salvo='1', shooter_salvo='1',firing_range='25') doctrine.set_weapon_release_authority(weapon_dbid='15',target_type='2202', quantity_salvo='1', shooter_salvo='1',firing_range='25') doctrine.set_weapon_release_authority(weapon_dbid='15',target_type='2203', quantity_salvo='1', shooter_salvo='1',firing_range='25') doctrine.set_weapon_release_authority(weapon_dbid='15',target_type='2204', quantity_salvo='1', shooter_salvo='1',firing_range='25') doctrine.set_weapon_release_authority(weapon_dbid='15',target_type='1999', quantity_salvo='1', shooter_salvo='1',firing_range='20') #第一个是空战巡逻任务,主要是执行对空作战的歼击机,进行空中巡逻。第二个是空战等待任务, #创建空战任务飞机的巡逻区(以驱逐舰为中心的八边形,内径长80km) a=0 ship=side.ships['6d829dba-2092-4b9d-a824-05ae1cb74c9b'] point_list='{type="AAW",Zone={' for i in range(8): temp=get_geopoint_from_distance(geo_point=(ship.dLatitude,ship.dLongitude), azimuth=22.5+i*45, distance_m=80*1000) side.addReferencePoint('AAW_Attack'+str(i),temp[0],temp[1]) if i!=7: point_list+=('"AAW_Attack'+str(i)+'",') else: point_list+=('"AAW_Attack'+str(i)+'"}}') print(point_list) side.add_mission('空战巡逻','Patrol',point_list) #创建突击任务飞机的巡逻区(以驱逐舰为中心的八边形,内径长30km) a=0 point_list='{type="AAW",Zone={' for i in range(8): temp=get_geopoint_from_distance(geo_point=(ship.dLatitude,ship.dLongitude), azimuth=22.5+i*45, distance_m=30*1000) side.addReferencePoint('AAW_Wait'+str(i),temp[0],temp[1]) if i!=7: point_list+=('"AAW_Wait'+str(i)+'",') else: point_list+=('"AAW_Wait'+str(i)+'"}}') side.add_mission('空战等待','Patrol',point_list) #创建突击任务 side.add_mission('对水攻击','STRIKE',"{type='LAND'}") #对每类飞机设置标签,记录当前信息。 self.AAW_Attack={} self.AAW_Wait={} for k,v in side.aircrafts.items(): temp=v.strName.split('#') if int(temp[1])>8: self.AAW_Attack[k]={'空战巡逻':True} else: self.AAW_Wait[k]={'空战等待':True, '对水攻击':False} #最后一行代码,是用来标记任务是否进行了设置,在step中会用到。 self.mission_setting=False def get_enmInfo(self, side): ''' 获取探测信息 ''' #print(side.contacts) airs=dict() air_missiles=dict() ship_missiles=dict() defense_missiles=dict() ships=dict() for k,v in side.contacts.items(): temp=v.get_contact_info() if temp['typed']==2: ships[k]={'name':temp['name'],'fg':temp['fg'],'longitude':temp['longitude'],'latitude':temp['latitude'], 'alt':temp['altitude'],'heading':temp['heading'],'speed':temp['speed']} if temp['typed']==1 and '导弹' in temp['name']: air_missiles[k]={'name':temp['name'],'fg':temp['fg'],'longitude':temp['longitude'],'latitude':temp['latitude'], 'alt':temp['altitude'],'heading':temp['heading'],'speed':temp['speed']} if temp['typed']==0: airs[k]={'name':temp['name'],'fg':temp['fg'],'longitude':temp['longitude'],'latitude':temp['latitude'], 'alt':temp['altitude'],'heading':temp['heading'],'speed':temp['speed']} if temp['typed']==1 and ('VAMPIRE' in temp['name'] or 'GuidedWeapon' in temp['name']): ship_missiles[k]={'name':temp['name'],'fg':temp['fg'],'longitude':temp['longitude'],'latitude':temp['latitude'], 'alt':temp['altitude'],'heading':temp['heading'],'speed':temp['speed']} if temp['typed']==1 and '防空' in temp['name'] : defense_missiles[k]={'name':temp['name'],'fg':temp['fg'],'longitude':temp['longitude'],'latitude':temp['latitude'], 'alt':temp['altitude'],'heading':temp['heading'],'speed':temp['speed']} #敌方飞机,舰船,空空弹,空地弹,地空弹 return airs,ships,air_missiles,ship_missiles,defense_missiles def my_step(self,side): ''' 实现自身的规则设计 ''' #获得己方任务对象,根据我们之前定义的名字,拿到被对象化的任务实例 for k,v in side.missions.items(): if '巡逻' in v.strName: AAW_Attack=v elif '等待' in v.strName: AAW_Wait=v else: LAND_Attack=v #获取敌方实体信息,接下来是我自己写的一个函数,用来对敌方的信息进行抽取,我将其分为飞机、舰船,空空弹,反舰弹,防空弹五类。 airs,ships,air_missiles,ship_missiles,defense_missiles=self.get_enmInfo(side) #记录敌方发射的空空弹 for k,v in air_missiles.items(): if k not in self.enm_miss: self.enm_miss.append(k) #获取敌方驱逐舰信息,我这里获取敌方的舰船guid,这个值是要传给打击任务的。 ship_target=None for k,v in ships.items(): if '驱逐舰' in v['name']: ship_target=k #首次进入对任务的规则进行设置 if not self.mission_setting: #巡逻任务:关闭三分之一,关闭防区外探测,设置单机编队,设置出航、阵位、攻击速度;设置高度。 AAW_Attack.set_one_third_rule('false') AAW_Attack.set_OPA_check(False) AAW_Attack.set_flight_size(FlightSize.One) AAW_Attack.set_throttle_transit(Throttle.Cruise) AAW_Attack.set_throttle_station(Throttle.Loiter) AAW_Attack.set_throttle_attack(Throttle.Loiter) AAW_Attack.set_transit_altitude(8000) AAW_Attack.set_station_altitude(8000) AAW_Attack.set_attack_altitude(8000) AAW_Wait.set_one_third_rule('false') AAW_Wait.set_OPA_check(False) AAW_Wait.set_flight_size(FlightSize.One) AAW_Wait.set_throttle_transit(Throttle.Cruise) AAW_Wait.set_throttle_station(Throttle.Loiter) AAW_Wait.set_throttle_attack(Throttle.Loiter) AAW_Wait.set_transit_altitude(8000) AAW_Wait.set_station_altitude(8000) AAW_Wait.set_attack_altitude(8000) #打击任务:设置单机编队,设置预先规划,添加打击目标,设置最小打击半径,设置多扇面攻击 LAND_Attack.set_flight_size(FlightSize.One) LAND_Attack.set_preplan(True) LAND_Attack.add_target([k]) LAND_Attack.set_min_strike_radius(30) LAND_Attack.set_auto_planner(True) self.mission_setting=True #规则实现,根据敌方的空中防御力量,判断是否发起对水攻击任务 if len(self.enm_miss)>60 or len(airs)<3: for k,v in self.AAW_Wait.items(): self.AAW_Wait[k]['对水攻击']=True self.AAW_Wait[k]['空战等待']=False else: for k,v in self.AAW_Wait.items(): self.AAW_Wait[k]['对水攻击']=False self.AAW_Wait[k]['空战等待']=True #获取任务的分配单元 AAW_Attack_list=AAW_Attack.get_assigned_mission() AAW_Wait_list=AAW_Wait.get_assigned_mission() LAND_Attack_target=LAND_Attack.get_targets() LAND_Attack_list=LAND_Attack.get_assigned_mission() #根据存储标识,将飞机分向指定任务 for k,v in self.AAW_Attack.items(): if k not in AAW_Attack_list and self.AAW_Attack[k]['空战巡逻']: #先清空出之前的任务 if k in LAND_Attack_list: LAND_Attack.scenEdit_unAssignUnitFromMission(k) #在分配至新任务 AAW_Attack.assignUnitToMission(k) for k,v in self.AAW_Wait.items(): if k not in AAW_Wait_list and self.AAW_Wait[k]['空战等待']: side.aircrafts[k].delete_coursed_point(clear=True) #先清空出之前的任务 if k in LAND_Attack_list: LAND_Attack.scenEdit_unAssignUnitFromMission(k) AAW_Wait.assignUnitToMission(k) if k not in LAND_Attack_list and self.AAW_Wait[k]['对水攻击']: #先清空出之前的任务 if k in AAW_Wait_list: AAW_Wait.scenEdit_unAssignUnitFromMission(k) LAND_Attack.assignUnitToMission(k) def get_mysideInfo(self, side): ''' 传入推演方 输出: { 'ships':{guid:{}}, 'airs':{guid:{}}, 'ship_missiles':{guid:{}}, 'air_missiles': {guid:{}} } ''' ships=dict() airs=dict() missiles=dict() for k,v in side.ships.items(): ships[k]={'latitude':v.dLatitude,'longitude':v.dLongitude,'name':v.strName} for k,v in side.aircrafts.items(): airs[k]={'latitude':v.dLatitude,'longitude':v.dLongitude,'alt':v.fCurrentAlt, 'speed':v.fDesiredSpeed,'name':v.strName} for k,v in side.weapons.items(): missiles[k]={'latitude':v.dLatitude,'longitude':v.dLongitude,'alt':v.fCurrentAlt, 'speed':v.fDesiredSpeed,'target':v.m_PrimaryTargetGuid,'from':v.m_FiringUnitGuid,'name':v.strName} return ships,airs, missiles
class MoziEnv(): def __init__(self, IP, AIPort, scenario_name, simulate_compression): self.control_noise = True self.SERVER_PLAT = "linux" self.SERVER_IP = IP self.SERVER_PORT = AIPort self.connect_mode = 1 self.DURATION_INTERVAL = etc.DURATION_INTERVAL self.simulate_compression = simulate_compression self.scenario_name = scenario_name self.mozi_service = MoziService(IP, AIPort, self.scenario_name, connect_mode=self.connect_mode) self.action_space = 4 self.action_max = 1 self.element_item_count = 8 self.observation_space = self.element_item_count * 4 # two red aircraft, two blue aircraft self.last_situation_time = None self.red_unit_list = None self.blue_unit_list = None self.observation = None self.red_side_name = "红方" self.blue_side_name = "蓝方" self.last_red_aircraft_num = 0 self.last_blue_aircraft_num = 0 self.red_aircraft_num = 0 self.blue_aircraft_num = 0 def _get_mounts_guid_lt(self, item_dic): mounts_str = item_dic["m_Mounts"] guid_lt = mounts_str.split("@") #pylog.info("%s mounts guid:%s" %(item_dic["strUnitClass"], guid_lt)) return guid_lt def _get_loadout_guid_lt(self, item_dic): mounts_str = item_dic["m_LoadoutGuid"] guid_lt = mounts_str.split("@") #pylog.info("%s loadout guid:%s" %(item_dic["strUnitClass"], guid_lt)) return guid_lt def _show_mounts_info(self, mounts_guid_lt): for mounts_guid in mounts_guid_lt: pylog.info("mount guid:%s" % mounts_guid) item = self.mozi_service.all_info_dict[mounts_guid] for key in item: pylog.info("%s:%s" % (key, item[key])) def _show_loadout_info(self, guid_lt): for loadout_guid in guid_lt: pylog.info("loadout guid:%s" % loadout_guid) item = self.mozi_service.all_info_dict[loadout_guid] pylog.info("strName:%s" % item["strName"]) pylog.info("m_AircraftGuid:%s" % item["m_AircraftGuid"]) pylog.info("strLoadWeaponCount:%s" % item["strLoadWeaponCount"]) pylog.info("m_LoadRatio:%s" % item["m_LoadRatio"]) #for key in item: # pylog.info("%s:%s" % (key, item[key])) def _init_red_unit_list(self): side_name = self.red_side_name ret_lt = [] side_guid = get_side_guid_from_side_name( side_name, self.mozi_service.all_info_dict) side_dic = get_a_side_dic(side_guid, self.mozi_service.all_info_dict) aircraft_list_dic = get_units_from_side( side_guid, "CAircraft", self.mozi_service.all_info_dict) for key in aircraft_list_dic: item = aircraft_list_dic[key] if item["strUnitClass"] == '苏-35S型“超级侧卫”战斗机': ret_lt.append(key) return ret_lt def _init_blue_unit_list(self): side_name = self.blue_side_name ret_lt = [] side_guid = get_side_guid_from_side_name( side_name, self.mozi_service.all_info_dict) side_dic = get_a_side_dic(side_guid, self.mozi_service.all_info_dict) aircraft_list_dic = get_units_from_side( side_guid, "CAircraft", self.mozi_service.all_info_dict) for key in aircraft_list_dic: item = aircraft_list_dic[key] if item["strUnitClass"] == 'F-15E型“攻击鹰式”战斗机': ret_lt.append(key) return ret_lt def _show_mounts_and_loadout(self): for guid in self.blue_unit_list: item = self.mozi_service.all_info_dict.get(guid, "") if item != "": mounts_guid_lt = self._get_mounts_guid_lt(item) #self._show_mounts_info(mounts_guid_lt) loadout_guid_lt = self._get_loadout_guid_lt(item) self._show_loadout_info(loadout_guid_lt) for guid in self.red_unit_list: item = self.mozi_service.all_info_dict.get(guid, "") if item != "": mounts_guid_lt = self._get_mounts_guid_lt(item) #self._show_mounts_info(mounts_guid_lt) loadout_guid_lt = self._get_loadout_guid_lt(item) self._show_loadout_info(loadout_guid_lt) def _init_unit_list(self): self.red_unit_list = self._init_red_unit_list() #pylog.info(len(self.red_unit_list)) self.last_red_aircraft_num = len(self.red_unit_list) self.blue_unit_list = self._init_blue_unit_list() #pylog.info(len(self.blue_unit_list)) self.last_blue_aircraft_num = len(self.blue_unit_list) def _get_a_side_observation(self, unit_list): obs_lt = [] num = 0 for key in unit_list: unit = self.mozi_service.all_info_dict.get(key, "") if unit: obs_lt.append(unit["fFuelConsumptionCruise"]) obs_lt.append(unit["dLongitude"]) obs_lt.append(unit["dLatitude"]) obs_lt.append(unit["fCurrentHeading"]) obs_lt.append(unit["fCurrentSpeed"]) obs_lt.append(unit["fCurrentAlt"]) obs_lt.append(unit["fPitch"]) obs_lt.append(unit["fRoll"]) num += 1 else: obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) return obs_lt, num def _get_blue_observation(self): unit_list = self.blue_unit_list obs_lt, num = self._get_a_side_observation(unit_list) self.blue_aircraft_num = num return obs_lt def _get_red_observation(self): unit_list = self.red_unit_list obs_lt, num = self._get_a_side_observation(unit_list) self.red_aircraft_num = num return obs_lt def _get_observation(self): red_obs_lt = self._get_red_observation() #pylog.info(red_obs_lt) blue_obs_lt = self._get_blue_observation() #pylog.info(blue_obs_lt) red_obs_lt.extend(blue_obs_lt) #pylog.info(red_obs_lt) self.observation = red_obs_lt return red_obs_lt def _set_duration_interval(self): self.mozi_service.mozi_task.sendAndRecv("Hs_OneTimeStop('Stop', %d)" % self.DURATION_INTERVAL) def _reset(self): ret = self.mozi_service.suspend_simulate() self.mozi_service.all_info_dict = {} self.scenario = self.mozi_service.load_scenario(plat=self.SERVER_PLAT) self._set_duration_interval() ret = self.mozi_service.set_run_mode() ret = self.mozi_service.set_simulate_compression( self.simulate_compression) ret = self.mozi_service.set_compression_mode(False) self._run_simulate() def _run_simulate(self): pylog.info("run simulation") return self.mozi_service.run_simulate() def _check_duration(self): update_situation_time = self.mozi_service.mozi_task.getCurrentTime() if self.last_situation_time != None: duration_time = float(update_situation_time) - float( self.last_situation_time) if int(duration_time) != self.DURATION_INTERVAL: pylog.error( "duration_time:%s is differet from etc.DURATION_INTERVAL:%s" % (duration_time, self.DURATION_INTERVAL)) self.last_situation_time = update_situation_time def _run_with_situation_data(self): self.mozi_service.update_situation(self.scenario) #self._check_duration() def _get_waypoint_heading(self, last_heading, action_value): current_heading = last_heading + action_value if current_heading < 0: current_heading += 360 if current_heading > 360: current_heading -= 360 return current_heading def _get_new_waypoint(self, heading, lat, lon, distance=20.0): dic = get_point_with_point_bearing_distance(lat, lon, heading, distance) return dic def _deal_point_data(self, waypoint): if self.control_noise: lon = str( float(waypoint["longitude"]) + random.random() / 10.0 - 0.05) lat = str( float(waypoint["latitude"]) + random.random() / 10.0 - 0.05) else: lon = str(waypoint["longitude"]), lat = str(waypoint["latitude"]), return lon, lat def _check_is_drop_sonobuoy(self, action_value): if action_value[1].item() > 0: return True return False def _get_aircraft_waypoint(self, action_value): obs = self.observation #pylog.info(obs) longitude = obs[0] latitude = obs[1] heading = obs[2] #waypoint_heading = self._get_waypoint_heading(heading, action_value[0].item() * 90) waypoint_heading = self._get_waypoint_heading(heading, action_value * 90) waypoint = self._get_new_waypoint(waypoint_heading, latitude, longitude) distance = get_target_distance(latitude, longitude) return waypoint, distance def _get_a_aircraft_waypoint(self, obs_item, action_value): longitude = obs_item[0] latitude = obs_item[1] heading = obs_item[2] waypoint_heading = self._get_waypoint_heading(heading, action_value * 90) #pylog.info("waypoint_heading:%s" % waypoint_heading) waypoint = self._get_new_waypoint(waypoint_heading, latitude, longitude) #pylog.info("waypoint:%s" % waypoint) return waypoint def _execute_action(self, action_value): count = 0 for guid in self.red_unit_list: #pylog.info(guid) #pylog.info("observation:%s" % self.observation) obs_item = self.observation[count * self.element_item_count:(count + 1) * self.element_item_count] #pylog.info("obs_item:%s" % obs_item) waypoint = self._get_a_aircraft_waypoint( obs_item, action_value[count].item()) #pylog.info(waypoint) aircraft = self.mozi_service.get_entity(guid) if aircraft: lon, lat = self._deal_point_data(waypoint) aircraft.set_waypoint(self.red_side_name, guid, lon, lat) #if True: #aircraft.set_up_throttleI(self.mozi_service.mozi_task) # aircraft.set_up_throttleI() #else: #aircraft.set_down_throttleI(self.mozi_service.mozi_task) # aircraft.set_down_throttleI() # if True: # aircraft.set_up_Alt(self.mozi_service.mozi_task) # else: # aircraft.set_down_Alt(self.mozi_service.mozi_task) else: pylog.debug("aircraft:%s has been destroyed" % guid) count += 1 # if self._check_is_find_target(): # target_guid = self._get_target_guid() # aircraft.autoattack_target(target_guid, self.mozi_service.mozi_task) # else: # if distance < etc.target_radius: # if self._check_is_drop_sonobuoy(action_value): # aircraft.drop_sonobuoy(self.red_side_name, "shallow", "active", self.mozi_service.mozi_task) # lon, lat = self._deal_point_data(waypoint) # aircraft.set_waypoint(self.red_side_name, guid, lon, lat, self.mozi_service.mozi_task) def _check_done(self): if not self._check_red_aircraft_exist(): #pylog.info("do not has any red aircraft exit") if not self._check_red_missile_exist(): #pylog.info("do not has any red missile exit") return True if not self._check_blue_aircraft_exist(): #pylog.info("do not has any blue aircraft exit") if not self._check_blue_missile_exist(): #pylog.info("do not has any blue missile exit") return True return False def _check_red_missile_exist(self): if self._get_red_missile_num() != 0: return True return False def _check_blue_missile_exist(self): if self._get_blue_missile_num() != 0: return True return False def _check_red_aircraft_exist(self): obs = self.observation for i in range(2 * self.element_item_count): if obs[i] != 0.0: return True return False def _check_blue_aircraft_exist(self): obs = self.observation for i in range(2 * self.element_item_count, 4 * self.element_item_count): if obs[i] != 0.0: return True return False def _check_target_exist(self): if not check_is_exist_target(etc.target_name, self.mozi_service.all_info_dict): return False return True def _get_target_guid(self): target_name = etc.target_name target_guid = get_target_contact_guid_from_target_name( self.red_side_name, target_name, self.mozi_service.all_info_dict) return target_guid def _get_reward(self, action_value): reward = 0.0 # get reward -1 when loss an aircraft reward += -(self.last_red_aircraft_num - self.red_aircraft_num) * 1 # get reward 1 when destroy an aircraft reward += (self.last_blue_aircraft_num - self.blue_aircraft_num) * 1 self.last_red_aircraft_num = self.red_aircraft_num self.last_blue_aircraft_num = self.blue_aircraft_num if reward != 0.0: pylog.info("reward:%s" % reward) pylog.info( "cur red aircraft num:%s cur blue aircraft num:%s" % (self.last_red_aircraft_num, self.last_blue_aircraft_num)) pylog.info( "cur red missile num:%s cur blue missile num:%s" % (self._get_red_missile_num(), self._get_blue_missile_num())) #self._show_mounts_and_loadout() return reward def _get_red_missile_num(self): side_name = self.red_side_name return self._get_missile_num(side_name) def _get_missile_num(self, side_name): missile_count = 0 side_guid = get_side_guid_from_side_name( side_name, self.mozi_service.all_info_dict) side_dic = get_a_side_dic(side_guid, self.mozi_service.all_info_dict) for key in side_dic: if side_dic[key]["ClassName"] == "CWeapon": missile_count += 1 #pylog.info(side_dic[key]) pylog.info("m_PrimaryTargetGuid:%s" % side_dic[key]["m_PrimaryTargetGuid"]) pylog.info("m_FiringUnitGuid:%s" % side_dic[key]["m_FiringUnitGuid"]) #for k in side_dic[key]: # pylog.info("%s:%s" % (k, side_dic[key][k])) return missile_count def _get_blue_missile_num(self): side_name = self.blue_side_name return self._get_missile_num(side_name) def reset(self): self._reset() self.mozi_service.init_situation(self.scenario) self._init_unit_list() obs = self._get_observation() return np.array(obs) def step(self, action): self._execute_action(action) self._run_with_situation_data() obs = self._get_observation() reward = self._get_reward(action) done = self._check_done() info = "" return np.array(obs), reward, done, info def connect_server(self): if not self.mozi_service.connect_mozi_server(self.SERVER_IP, self.SERVER_PORT): return False else: return True
class MoziEnv(): def __init__(self, IP, AIPort, scenario_name, simulate_compression): self.control_noise = True self.SERVER_PLAT = "linux" self.SERVER_IP = IP self.SERVER_PORT = AIPort self.connect_mode = 1 self.DURATION_INTERVAL = etc.DURATION_INTERVAL self.simulate_compression = simulate_compression self.scenario_name = scenario_name self.mozi_service = MoziService(IP, AIPort, self.scenario_name, connect_mode=self.connect_mode) self.action_space = 4 self.action_max = 1 self.observation_space = 4 * 3 self.element_item_count = 4 self.last_situation_time = None self.red_unit_list = None self.blue_unit_list = None self.observation = None self.red_side_name = "红方" self.blue_side_name = "蓝方" def connect_server(self): if not self.mozi_service.connect_mozi_server(self.SERVER_IP, self.SERVER_PORT): return False else: return True def _init_red_unit_list(self): side_name = self.red_side_name ret_lt = [] side_guid = get_side_guid_from_side_name( side_name, self.mozi_service.all_info_dict) side_dic = get_a_side_dic(side_guid, self.mozi_service.all_info_dict) redfacility_list_dic = get_units_from_side( side_guid, "CFacility", self.mozi_service.all_info_dict) for key in redfacility_list_dic: ret_lt.append(key) return ret_lt def _init_blue_unit_list(self): side_name = self.blue_side_name ret_lt = [] side_guid = get_side_guid_from_side_name( side_name, self.mozi_service.all_info_dict) blufacility_list_dic = get_units_from_side( side_guid, "CFacility", self.mozi_service.all_info_dict) for key in blufacility_list_dic: ret_lt.append(key) return ret_lt def _init_unit_list(self): # 方法生成属性 self.red_unit_list = self._init_red_unit_list() self.blue_unit_list = self._init_blue_unit_list() def _get_a_side_observation(self, unit_list): obs_lt = [] for key in unit_list: unit = self.mozi_service.all_info_dict.get(key, "") if unit: obs_lt.append(unit["dLongitude"]) obs_lt.append(unit["dLatitude"]) obs_lt.append(unit["fCurrentSpeed"]) obs_lt.append(unit["fCurrentHeading"]) else: pylog.info("unit do not exist") obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) return obs_lt def _get_blue_observation(self): unit_list = self.blue_unit_list obs_lt = self._get_a_side_observation(unit_list) return obs_lt def _get_red_observation(self): unit_list = self.red_unit_list obs_lt = self._get_a_side_observation(unit_list) return obs_lt def _get_observation(self): red_obs_lt = self._get_red_observation() self.observation = red_obs_lt if not self._check_tank_exist(): if etc.TRANS_DATA: lt = [] lt.append(red_obs_lt[0] - etc.task_end_point["longitude"]) lt.append(red_obs_lt[1] - etc.task_end_point["latitude"]) lt.append(red_obs_lt[2] / 360) return lt return red_obs_lt def _set_duration_interval(self): self.mozi_service.mozi_task.sendAndRecv("Hs_OneTimeStop('Stop', %d)" % self.DURATION_INTERVAL) def _reset(self): ret = self.mozi_service.suspend_simulate() self.mozi_service.all_info_dict = {} self.scenario = self.mozi_service.load_scenario(plat=self.SERVER_PLAT) self._set_duration_interval() ret = self.mozi_service.set_run_mode() ret = self.mozi_service.set_simulate_compression( self.simulate_compression) ret = self.mozi_service.set_compression_mode(False) self._run_simulate() def _run_simulate(self): pylog.info("run simulation") return self.mozi_service.run_simulate() def _check_duration(self): update_situation_time = self.mozi_service.mozi_task.getCurrentTime() if self.last_situation_time != None: duration_time = float(update_situation_time) - float( self.last_situation_time) if int(duration_time) != self.DURATION_INTERVAL: pylog.error( "duration_time:%s is differet from etc.DURATION_INTERVAL:%s" % (duration_time, self.DURATION_INTERVAL)) self.last_situation_time = update_situation_time def _run_with_situation_data(self): self.mozi_service.update_situation(self.scenario) # self._check_duration() def _get_waypoint_heading(self, last_heading, action_value): current_heading = last_heading + action_value if current_heading < 0: current_heading += 360 if current_heading > 360: current_heading -= 360 return current_heading def _get_new_waypoint(self, heading, lat, lon, distance=20.0): dic = get_point_with_point_bearing_distance(lat, lon, heading, distance) return dic def _deal_point_data(self, waypoint): if self.control_noise: lon = str( float(waypoint["longitude"]) + random.random() / 10.0 - 0.05) lat = str( float(waypoint["latitude"]) + random.random() / 10.0 - 0.05) else: lon = str(waypoint["longitude"]), lat = str(waypoint["latitude"]), return lon, lat def _get_tank_waypoint(self, obs, action_value): longitude = obs[0] latitude = obs[1] heading = obs[2] waypoint_heading = self._get_waypoint_heading(heading, action_value * 90) waypoint = self._get_new_waypoint(waypoint_heading, latitude, longitude) distance = get_target_distance(latitude, longitude) return waypoint, distance def _execute_action(self, action_value): pylog.info(action_value) count = 0 for guid in self.red_unit_list: obs_item = self.observation[count * self.element_item_count:(count + 1) * self.element_item_count] waypoint, distance = self._get_tank_waypoint( obs_item, action_value[count].item()) tank = self.mozi_service.get_entity(guid) if distance < etc.target_radius: target_guid = self._get_target_guid( ) # 只有1个,如果一个red, 可以检测到多个怎么办? tank.fac_attack_auto(target_guid) else: if tank: lon, lat = self._deal_point_data(waypoint) tank.set_waypoint(self.red_side_name, guid, lon, lat) count += 1 def _check_done(self): if not self._check_tank_exist(): return True if not self._check_target_exist(): return True return False def _check_tank_exist(self): obs = self.observation for i in range(len(obs)): if obs[i] != 0.0: return True return False def _check_target_exist(self): if not check_is_exist_target(etc.target_name, self.mozi_service.all_info_dict): return False return True def _get_target_guid(self): target_name = etc.target_name target_guid = get_target_contact_guid_from_target_name( self.red_side_name, target_name, self.mozi_service.all_info_dict) return target_guid def _check_is_find_target(self): target_guid = self._get_target_guid() if target_guid: pylog.info("find target_guid:%s" % target_guid) return True return False def _get_distance_reward(self, num, action_value): obs = self.observation longitude = obs[0] latitude = obs[1] heading = obs[2] distance = get_target_distance(latitude, longitude) # action_change_heading = action_value[0].item() * 90 action_change_heading = action_value[num].item() * 90 reward = get_distance_reward(latitude, longitude, heading, action_change_heading) return reward, distance def _get_reward(self, action_value): # reward = 0 sum_reward = [] count = 0 for i in range(len(self.red_unit_list)): # 一直是3个?,应该用更新后的。 reward = 0 distance_reward, distance = self._get_distance_reward( i, action_value) reward += distance_reward if self._check_is_find_target(): reward += 10.0 if distance < etc.target_radius: reward += 10.0 if not self._check_tank_exist(): reward += -100.0 # 红方打掉蓝方坦克, 加100 # if distance < etc.target_radius: # 其实就是距离的奖赏值。只不过在距离范围内,值增加的更多。保留。 # reward += 10.0 # # else: # # if not self._check_tank_exist(): # # # pylog.info("tank is not exist get -100.0 reward") # # reward += -100.0 # elif not self._check_tank_exist(): # reward += -100.0 # elif self._check_is_find_target(): # reward += 10.0 # # elif not self._check_target_exist(): # pylog.info("destroy target get 150.0 reward") # reward += 150.0 # else: # print('没有用的else语句') sum_reward.append(reward) count += 1 return sum(sum_reward) def reset(self): self._reset() self.mozi_service.init_situation(self.scenario) self._init_unit_list() obs = self._get_observation() return np.array(obs) def step(self, action): self._execute_action(action) self._run_with_situation_data() # 更新,update obs = self._get_observation() reward = self._get_reward(action) done = self._check_done() info = "" return np.array(obs), reward, done, info
class MoziEnv(): def __init__(self, IP, AIPort, scenario_name, simulate_compression): self.control_noise = True self.SERVER_PLAT = "linux" self.SERVER_IP = IP self.SERVER_PORT = AIPort self.connect_mode = 1 self.DURATION_INTERVAL = etc.DURATION_INTERVAL self.simulate_compression = simulate_compression self.scenario_name = scenario_name self.mozi_service = None self.action_space = 4 self.action_max = 1 self.observation_space = 4 * 3 self.element_item_count = 4 self.last_situation_time = None self.red_unit_list = None self.blue_unit_list = None self.observation = None self.red_side_name = "红方" self.blue_side_name = "蓝方" def connect_mozi_server(self, websocket_Ip, websocket_port): """ 连接墨子服务器 param : websocket_server 要连接的服务器的ip websocket_port 要连接的服务器的端口 :return: """ pylog.info("connect_mozi_server") if self.connect_mode == 1: self.mozi_service = MoziService(websocket_Ip, websocket_port, self.scenario_name) return True # server_address = r"ws://%s:%d/websocket" % ('60.205.207.206', 9998) server_address = r"ws://%s:%d/websocket" % (websocket_Ip, websocket_port) pylog.info(server_address) for i in range(10): try: self.websocket_connect = create_connection(server_address) break except: pylog.info("can not connect to %s." % server_address) time.sleep(2) self.websocket_connect = None # if self.websocket_connect is None: pylog.warning("Interrupted, can not connect to %s." % server_address) return False # self.websocket_connect.send("{\"RequestType\":\"StartServer\"}") result = self.websocket_connect.recv() print("connect server result:%s" % result) jsons = json.loads(result) self.ai_server = jsons['IP'] self.ai_port = jsons['AIPort'] self.mozi_task = MoziService(self.server_ip, self.aiPort, self.scenario_name) return True #def connect_server(self): #if not self.mozi_service.connect_mozi_server(self.SERVER_IP, self.SERVER_PORT): #return False #else: #return True def _init_red_unit_list(self): side_name = self.red_side_name ret_lt = [] side_guid = get_side_guid_from_side_name( side_name, self.mozi_service.all_info_dict) side_dic = get_a_side_dic(side_guid, self.mozi_service.all_info_dict) redaircraft_list_dic = get_units_from_side( side_guid, "CAircraft", self.mozi_service.all_info_dict) for key in redaircraft_list_dic: ret_lt.append(key) return ret_lt def _init_blue_unit_list(self): side_name = self.blue_side_name ret_lt = [] side_guid = get_side_guid_from_side_name( side_name, self.mozi_service.all_info_dict) blufacility_list_dic = get_units_from_side( side_guid, "CFacility", self.mozi_service.all_info_dict) for key in blufacility_list_dic: ret_lt.append(key) return ret_lt def _init_unit_list(self): # 方法生成属性 self.red_unit_list = self._init_red_unit_list() self.blue_unit_list = self._init_blue_unit_list() def _get_a_side_observation(self, unit_list): obs_lt = [] for key, unit in unit_list.items(): if unit: obs_lt.append(unit.dLongitude) obs_lt.append(unit.dLatitude) obs_lt.append(unit.fCurrentSpeed) obs_lt.append(unit.fCurrentHeading) else: pylog.info("unit do not exist") obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) obs_lt.append(0.0) return obs_lt def _get_blue_observation(self): unit_list = self.blue_unit_list obs_lt = self._get_a_side_observation(unit_list) return obs_lt def _get_red_observation(self): ''' 获取红方得态势信息 ''' side_dic = self.scenario.situation.side_dic for key, side in side_dic.items(): if side.strName == '红方': unit_list = side.get_all_unitinfo() break obs_lt = self._get_a_side_observation(unit_list) return obs_lt def _get_observation(self): red_obs_lt = self._get_red_observation() self.observation = red_obs_lt if not self._check_tank_exist(): if etc.TRANS_DATA: lt = [] lt.append(red_obs_lt[0] - etc.task_end_point["longitude"]) lt.append(red_obs_lt[1] - etc.task_end_point["latitude"]) lt.append(red_obs_lt[2] / 360) return lt return red_obs_lt def _set_duration_interval(self): self.mozi_service.sendAndRecv("Hs_OneTimeStop('Stop', %d)" % self.DURATION_INTERVAL) def _reset(self): ret = self.mozi_service.suspend_simulate() self.mozi_service.all_info_dict = {} self.scenario = self.mozi_service.load_scenario(plat=self.SERVER_PLAT) self._set_duration_interval() ret = self.mozi_service.set_run_mode() ret = self.mozi_service.set_simulate_compression( self.simulate_compression) ret = self.mozi_service.set_compression_mode(False) self._run_simulate() def _run_simulate(self): pylog.info("run simulation") return self.mozi_service.run_simulate() def _check_duration(self): update_situation_time = self.mozi_service.mozi_task.getCurrentTime() if self.last_situation_time != None: duration_time = float(update_situation_time) - float( self.last_situation_time) if int(duration_time) != self.DURATION_INTERVAL: pylog.error( "duration_time:%s is differet from etc.DURATION_INTERVAL:%s" % (duration_time, self.DURATION_INTERVAL)) self.last_situation_time = update_situation_time def _run_with_situation_data(self): self.mozi_service.update_situation(self.scenario) # self._check_duration() def _get_waypoint_heading(self, last_heading, action_value): current_heading = last_heading + action_value if current_heading < 0: current_heading += 360 if current_heading > 360: current_heading -= 360 return current_heading def _get_new_waypoint(self, heading, lat, lon, distance=20.0): dic = get_point_with_point_bearing_distance(lat, lon, heading, distance) return dic def _deal_point_data(self, waypoint): if self.control_noise: lon = str( float(waypoint["longitude"]) + random.random() / 10.0 - 0.05) lat = str( float(waypoint["latitude"]) + random.random() / 10.0 - 0.05) else: lon = str(waypoint["longitude"]), lat = str(waypoint["latitude"]), return lon, lat def _get_tank_waypoint(self, obs, action_value): longitude = obs[0] latitude = obs[1] heading = obs[2] waypoint_heading = self._get_waypoint_heading(heading, action_value * 90) waypoint = self._get_new_waypoint(waypoint_heading, latitude, longitude) distance = get_target_distance(latitude, longitude) return waypoint, distance def _execute_action(self, action_value): pylog.info(action_value) count = 0 for guid in self.red_unit_list: obs_item = self.observation[count * self.element_item_count:(count + 1) * self.element_item_count] waypoint, distance = self._get_tank_waypoint( obs_item, action_value[count].item()) tank = self.mozi_service.get_entity(guid) if distance < etc.target_radius: target_guid = self._get_target_guid( ) # 只有1个,如果一个red, 可以检测到多个怎么办? tank.fac_attack_auto(target_guid) else: if tank: lon, lat = self._deal_point_data(waypoint) tank.set_waypoint(self.red_side_name, guid, lon, lat) count += 1 def _check_done(self): if not self._check_tank_exist(): return True if not self._check_target_exist(): return True return False def _check_tank_exist(self): obs = self.observation for i in range(len(obs)): if obs[i] != 0.0: return True return False def _check_target_exist(self): if not check_is_exist_target(etc.target_name, self.mozi_service.all_info_dict): return False return True def _get_target_guid(self): target_name = etc.target_name target_guid = get_target_contact_guid_from_target_name( self.red_side_name, target_name, self.mozi_service.all_info_dict) return target_guid def _check_is_find_target(self): target_guid = self._get_target_guid() if target_guid: pylog.info("find target_guid:%s" % target_guid) return True return False def _get_distance_reward(self, num, action_value): obs = self.observation longitude = obs[0] latitude = obs[1] heading = obs[2] distance = get_target_distance(latitude, longitude) # action_change_heading = action_value[0].item() * 90 action_change_heading = action_value[num].item() * 90 reward = get_distance_reward(latitude, longitude, heading, action_change_heading) return reward, distance def _get_reward(self, action_value): # reward = 0 sum_reward = [] count = 0 for i in range(len(self.red_unit_list)): # 一直是3个?,应该用更新后的。 reward = 0 distance_reward, distance = self._get_distance_reward( i, action_value) reward += distance_reward if self._check_is_find_target(): reward += 10.0 if distance < etc.target_radius: reward += 10.0 if not self._check_tank_exist(): reward += -100.0 # 红方打掉蓝方坦克, 加100 # if distance < etc.target_radius: # 其实就是距离的奖赏值。只不过在距离范围内,值增加的更多。保留。 # reward += 10.0 # # else: # # if not self._check_tank_exist(): # # # pylog.info("tank is not exist get -100.0 reward") # # reward += -100.0 # elif not self._check_tank_exist(): # reward += -100.0 # elif self._check_is_find_target(): # reward += 10.0 # # elif not self._check_target_exist(): # pylog.info("destroy target get 150.0 reward") # reward += 150.0 # else: # print('没有用的else语句') sum_reward.append(reward) count += 1 return sum(sum_reward) def reset(self): self._reset() self.mozi_service.init_situation(self.scenario) #self._init_unit_list() obs = self._get_observation() return np.array(obs) ''' #by aie def step(self, action): self._execute_action(action) self._run_with_situation_data() # 更新,update obs = self._get_observation() reward = self._get_reward(action) done = self._check_done() info = "" return np.array(obs), reward, done, info ''' #by aie def step(self): self._run_with_situation_data() # 更新,update return True