def __pt_stub(df: pandas.DataFrame, lpos: Point3D): df['aggr_light_values'] = df['light_values'].apply( lambda lvs: max(lvs.values())) score = df['aggr_light_values'].sum(axis=0, skipna=True) max_step = df['n_step'].max() fpos = df[df['n_step'] == max_step]['position'].T.values[0] return (1 / score if score > 0 else float('+inf')), round( lpos.dist(fpos), 5)
def r_point3d(O=Point3D(0.0, 0.0, 0.0), R=1.0, axis=Axis.NONE, quadrant=Quadrant.ANY): R = R if isinstance(R, (list, tuple)) and len(R) > 1 else flat([0.0, R]) r = min(R) + abs(R[0] - R[1]) * np.random.uniform(0, 1.0) if axis is Axis.NONE: el = math.acos(1.0 - np.random.uniform(0.0, 2.0)) # better distribution but fails for Z | X == 0 else: el = np.random.uniform(0.0, 1.0) * 2 * math.pi az = np.random.uniform(0.0, 1.0) * 2 * math.pi return O + quadrant(axis(r, el, az))
def __call__(self, morphology: EPuckMorphology, step: int, timestep: int, force_sensing=False) -> SimulationStepData: # BN update is faster than sensor sampling frequency for k, led in morphology.led_actuators.items(): # print(k, led.device) led.device.set(self.led_color) if self.__next_sensing == 0 or self.__next_sensing == step or force_sensing: self.__next_sensing += int(self.__sensing_interval / timestep) # Retreive Sensors Data self.gps_data = [ Point3D.from_tuple(g.read()) for g in morphology.GPSs.values() ] self.light_data = dict( (k, l.read()) for k, l in morphology.light_sensors.items()) # Apply Binarization Strategies bin_light_data = self.__bin_strategies[DeviceName.LIGHT]( self.light_data, self.__bin_thresholds[DeviceName.LIGHT]) # "Perturbate" network based on binarized values # This should be applied each time on input nodes for l in self.__bn.input_nodes: self.__bn[l].state = bin_light_data[l] # Update network state bn_state = self.__bn.update() # Apply Network Output to actuators lv, rv, *_ = [ self.__bn[k].state for k in sorted(self.__bn.output_nodes) ] morphology.wheel_actuators['left'].device.setVelocity(lv) morphology.wheel_actuators['right'].device.setVelocity(rv) return SimulationStepData(step, self.gps_data[0], bn_state, self.light_data, self.distance_data, self.touch_data)
class DefaultConfigOptions(Jsonkin): __def_options=dict( app_output_path=DefaultOption( value=Path('.'), type=Path, alt=None, descr='''Directory or file where to store the simulation general log''' ), app_core_function=DefaultOption( value=FunctionWrapper('bncontroller.sim.config::empty'), type=FunctionWrapper, alt=None, descr='''Core function called by main holding the experiment procedure''' ), # eval_aggr_function=DefaultOption( value=FunctionWrapper('bncontroller.sim.config::empty'), type=FunctionWrapper, alt=None, descr='''value to which reduce the objective function''' ), # eval_cmp_function=DefaultOption( value=FunctionWrapper('bncontroller.sim.config::empty'), type=FunctionWrapper, alt=None, descr='''comparator of the evaluation scores''' ), # # Simulator Launch Options # webots_path=DefaultOption( value=Path('.'), type=Path, alt=None, descr='''path to webots executable''' ), webots_world_path=DefaultOption( value=Path('.'), type=Path, alt=None, descr='''path to webots world file''' ), webots_launch_opts=DefaultOption( value=["--mode=fast", "--batch", "--minimize"], type=str, alt=None, descr='''simulator command line arguements''' ), webots_quit_on_termination=DefaultOption( value=True, type=bool, alt=None, descr='''quit simulator after simulation ends''' ), webots_nodes_defs=DefaultOption( value=dict(), type=str, alt=dict, descr='''simulation world node definitions (node custom names)''' ), webots_agent_controller=DefaultOption( value='none', type=str, alt=None, descr='''simulation world node definitions (node custom names)''' ), webots_arena_size=DefaultOption( value=(3.0, 3.0), type=float, alt=tuple, descr='''simulation world arena size''' ), # Stochastic Descent Algorithm Control Parameters # sd_max_iters=DefaultOption( value=10000, type=int, alt=None, descr='''stochastic descent max iterations''' ), sd_min_flips=DefaultOption( value=1, type=int, alt=None, descr='''stochastic descent min flipped TT entries by iteration''' ), sd_max_stalls=DefaultOption( value=1, type=int, alt=None, descr='''-1 -> Adaptive Walk, 0+ -> VNS''' ), sd_max_stagnation=DefaultOption( value=1250, type=int, alt=None, descr='''close the algorithm if no further improvement are found after i iteration''' ), sd_target_score=DefaultOption( value=0.0, type=float, alt=tuple, descr='''value to which reduce the objective function''' ), # # Simulation Control Options # sim_run_time_s=DefaultOption( value=60, type=int, alt=None, descr='''execution time of the simulation in seconds''' ), sim_timestep_ms=DefaultOption( value=32, type=int, alt=None, descr='''simulation Loop synch time in ms''' ), sim_sensing_interval_ms=DefaultOption( value=320, type=int, alt=None, descr='''execution time of the simulation in milli-seconds''' ), sim_sensors_thresholds=DefaultOption( value={ DeviceName.DISTANCE: 0.0, DeviceName.LIGHT: 0.0, DeviceName.LED: 0.0, DeviceName.TOUCH: 0.0, DeviceName.WHEEL_MOTOR: 0.0, DeviceName.WHEEL_POS: 0.0, DeviceName.GPS: 0.0, }, type=float, alt=dict, descr='''sensors threshold to apply as binarization filters''' ), sim_event_timer_s=DefaultOption( value=-1, type=int, alt=None, descr='''perturbation event triggered after t seconds. if -1 => not triggered.''' ), sim_light_position=DefaultOption( value=Point3D(0.0, 0.0, 0.0), type=Point3D, alt=None, descr='''origin spawn point for light source''' ), sim_light_intensity=DefaultOption( value=1.0, type=float, alt=None, descr='''light source intensity''' ), sim_agent_position=DefaultOption( value=Point3D(0.0, 0.0, 0.0), type=Point3D, alt=None, descr='''origin Spawn point for agents''' ), sim_agent_yrot_rad=DefaultOption( value=0.0, type=float, alt=None, descr='''agent spawn orientation''' ), sim_suppress_logging=DefaultOption( value=True, type=bool, alt=None, descr='''shut the simulation logger unit''' ), sim_config_path=DefaultOption( value=Path('.'), type=Path, alt=None, descr='''Directory or file where to store the simulation config''' ), sim_data_path=DefaultOption( value=Path('.'), type=Path, alt=None, descr='''Directory or file where to store the simulation data''' ), sim_log_path=DefaultOption( value=Path('.'), type=Path, alt=None, descr='''Directory or file where to store the simulation general log''' ), sim_unique_data_file=DefaultOption( value=False, type=bool, alt=None, descr='''Whether or not each simulation (of a single run) have to use the same data file or not''' ), # Boolean Networks Generation Control Parameters # bn_model_path=DefaultOption( value=Path('.'), type=Path, alt=None, descr='''Directory or file where to store the bn model''' ), # bn_model_path=DefaultOption( # value=Path('.'), # type=Path, # alt=None, # descr='''Directory or file where to store the bn selector model''' # ), bn_n=DefaultOption( value=20, type=int, alt=None, descr='''boolean Network cardinality''' ), bn_k=DefaultOption( value=2, type=int, alt=None, descr='''boolean Network Node arity''' ), bn_p=DefaultOption( value=0.5, type=float, alt=None, descr='''truth table value bias''' ), bn_q=DefaultOption( value=0.5, type=float, alt=None, descr='''bn node intial state bias''' ), bn_n_inputs=DefaultOption( value=8, type=int, alt=None, descr='''number of nodes of the BN to be reserved as inputs''' ), bn_n_outputs=DefaultOption( value=2, type=int, alt=None, descr='''number of nodes of the BN to be reserved as outputs''' ), slct_behaviours_map=DefaultOption( value=dict(), type=Path, alt=dict, descr='''mapping attractor -> behaviour bn model path''' ), slct_target_n_attractors=DefaultOption( value=2, type=int, alt=None, descr='''number of wanted attractors''' ), slct_target_transition_tau=DefaultOption( value=dict(), type=float, alt=dict, descr='''probability to jump from an attractor to another different from itself.''', ), # slct_in_attr_map=DefaultOption( # value=[ # [False], # [True] # ], # type=Path, # alt=None, # descr='''specifify the input values to apply to input nodes for that attractor''' # ), slct_noise_rho=DefaultOption( value=0.1, type=float, alt=None, descr='''Probability of noise to flip the state of a BN''' ), # slct_input_step_frac=DefaultOption( # value=1/5, # type=Path, # alt=None, # descr='''Fractions of update steps (it) on each which apply inputs on input node.''' # ), slct_input_steps_phi=DefaultOption( value=1, type=int, alt=None, descr='''For how many steps the input should be enforced in the network (after each sensing)''' ), # Evaluation Parameters eval_agent_spawn_radius_m=DefaultOption( value=0.5, type=float, alt=None, descr='''spawn radius of the agent''' ), # eval_agent_offset_quadrant=DefaultOption( value='ANY', type=str, alt=None, descr='''spawn quadrant of the agent''' ), # eval_light_spawn_radius_m=DefaultOption( value=0.5, type=float, alt=None, descr='''spawn radius of the light point''' ), eval_light_offset_quadrant=DefaultOption( value='ANY', type=str, alt=None, descr='''spawn quadrant of the light point''' ), eval_n_agent_spawn_points=DefaultOption( value=1, type=int, alt=None, descr='''How many agent position to evaluate, If 0 uses always the same point (specified in sim_agent_position) to spawn the agent''' ), eval_n_light_spawn_points=DefaultOption( value=1, type=int, alt=None, descr='''How many light position to evaluate, If 0 uses always the same point (specified in sim_light_position) to spawn the light''' ), eval_agent_yrot_start_rad=DefaultOption( value=0.0, type=float, alt=None, descr='''From where to start sampling the yrot angles''' ), eval_agent_n_yrot_samples=DefaultOption( value=6, type=int, alt=None, descr='''Number of rotation to evaluate If 0 uses always the same value (specified in sim_agent_yrot_rad) to set the agent rotation''' ), # Model Test Control Parameters # plot_positives_threshold=DefaultOption( value=2e-06, type=float, alt=None, descr='''Specify a score threshold under which model are considered "good"''' ), plot_image_path=DefaultOption( value=Path('.'), type=Path, alt=None, descr='''ath where to store / read plot images''' ), test_data_path=DefaultOption( value=Path('.'), type=Path, alt=None, descr='''Path where to store / read test data''' ), test_n_instances=DefaultOption( value=1, type=int, alt=None, descr='''Number of instances of the test cycle for each bn''' ), # test_aggr_function=DefaultOption( # value=FunctionWrapper('bncontroller.sim.config::empty'), # type=Path, # alt=None, # descr='''how test parameters should be aggregated in the test loop''' # ), # Train control parameters# train_save_suboptimal_models=DefaultOption( value=2e-06, type=float, alt=tuple, descr='''save bn model with score under the specified threshold''' ), train_generate_only=DefaultOption( value=False, type=bool, alt=None, descr='''Only generate training bn without running SD''' ) ) @staticmethod def options(): return dict(DefaultConfigOptions.__def_options) @staticmethod def default(): return dict((k, o.value) for k, o in DefaultConfigOptions.options().items()) @staticmethod def keys(): return DefaultConfigOptions.__def_options.keys() @staticmethod def values(): return DefaultConfigOptions.__def_options.values()
def from_tuple(coordinates): return Point3D(coordinates[0], coordinates[1], coordinates[2])
def from_json(json: dict): return Point3D( json['x'], json['y'], json['z'] )
def from_polar(r, el, az): return Point3D( x = r * math.sin(el) * math.sin(az), y = r * math.cos(el), z = r * math.sin(el) * math.cos(az) )
def __abs__(self): return Point3D(abs(self.x), abs(self.y), abs(self.z))
def __add__(self, that): return Point3D(self.x + that.x, self.y + that.y, self.z + that.z)
fig = plotter.figure() ax = fig.gca(projection='3d') ax.set_xlabel('X') ax.set_ylabel('Z') ax.set_zlabel('Y') ax.set_xlim3d([-8.0, 8.0]) ax.set_ylim3d([-8.0, 8.0]) ax.set_zlim3d([-8.0, 8.0]) xs = [] ys = [] zs = [] for _ in range(1000): p1 = r_point3d(O=Point3D(4.0, 0.0, -4.0), R=[0.0, 3.0], axis=Axis.NONE, quadrant=Quadrant.ANY) p2 = r_point3d(O=Point3D(4.0, 0.0, 4.0), R=[1.0, 3.0], axis=Axis.NONE, quadrant=Quadrant.ANY) p3 = r_point3d(O=Point3D(-4.0, 0.0, -4.0), R=[3.0, 3.0], axis=Axis.NONE, quadrant=Quadrant.ANY) px = r_point3d(O=Point3D(-4.0, 0.0, 4.0), R=[2.0, 3.0], axis=Axis.X, quadrant=Quadrant.ANY) py = r_point3d(O=Point3D(-4.0, 0.0, 4.0), R=[2.0, 3.0], axis=Axis.Y, quadrant=Quadrant.ANY) pz = r_point3d(O=Point3D(-4.0, 0.0, 4.0), R=[2.0, 3.0], axis=Axis.Z, quadrant=Quadrant.ANY) # print(p.to_tuple()) xs.extend([p1.x, p2.x, p3.x, px.x, py.x, pz.x]) ys.extend([p1.y, p2.y, p3.y, px.y, py.y, pz.y]) zs.extend([p1.z, p2.z, p3.z, px.z, py.z, pz.z]) ax.scatter(xs, zs, ys) plotter.show()
def sbnc(sim_data: dict, lpos: Point3D) -> (float, float): df = pandas.DataFrame(sim_data['data']) def get_attr(df, attr, default): return df[attr] if attr in df else default def get_attr_ratio(df, a1, a2): v1 = get_attr(df, a1, 0) v2 = get_attr(df, a2, 0) if v2 > 0: return v1 / v2 else: return math.inf noise_phase_data = df[df['noise'] == True] phase_l = int(len(noise_phase_data) / 2) pt_data = df[(df['input'] == 0) & (df['noise'] == False)] apt_data = df[(df['input'] == 1) & (df['noise'] == False)] ################################################################## noise1_a01_count = noise_phase_data[:phase_l]['attr'].value_counts() noise1_a0_count = get_attr(noise1_a01_count, 'a0', 0) noise1_a1_count = get_attr(noise1_a01_count, 'a1', 0) # print(noise1_a0_count, noise1_a1_count) # noise1_score = get_attr_ratio(noise1_a01_count) ################################################################## noise2_a01_count = noise_phase_data[phase_l:]['attr'].value_counts() noise2_a0_count = get_attr(noise2_a01_count, 'a0', 0) noise2_a1_count = get_attr(noise2_a01_count, 'a1', 0) # print(noise2_a0_count, noise2_a1_count) # noise2_score = get_attr_ratio(noise2_a01_count) ################################################################## pt_score, pt_fdist = __pt_stub(pt_data, lpos) # minimize+ pt_a01_count = pt_data['attr'].value_counts() pt_a01_ratio = get_attr_ratio(pt_a01_count, 'a0', 'a1') # print(pt_a01_ratio) ################################################################## apt_score, apt_fdist = __pt_stub(apt_data, lpos) # maximize apt_a01_count = apt_data['attr'].value_counts() apt_a01_ratio = get_attr_ratio(apt_a01_count, 'a0', 'a1') # print(apt_a01_ratio) ################################################################## pt_apos = pt_data.iloc[0]['position'] pt_fapos = pt_data.iloc[-1]['position'] apt_apos = apt_data.iloc[0]['position'] apt_fapos = apt_data.iloc[-1]['position'] apt_ilv = [*apt_data.iloc[0]['light_values'].values()] apt_flv = [*apt_data.iloc[-1]['light_values'].values()] pt_ilv = [*pt_data.iloc[0]['light_values'].values()] apt_yrot_idx = apt_ilv.index(max(apt_ilv)) apt_yrot = EPuckMorphology.LIGHT_SENSORS_POSITION[apt_yrot_idx] apt_fyrot_idx = apt_flv.index(max(apt_flv)) apt_fyrot = EPuckMorphology.LIGHT_SENSORS_POSITION[apt_fyrot_idx] pt_yrot_idx = pt_ilv.index(max(pt_ilv)) pt_yrot = EPuckMorphology.LIGHT_SENSORS_POSITION[pt_yrot_idx] return ( { # 'noise1_score': noise1_score, 'noise1_a0_count': noise1_a0_count, 'noise1_a1_count': noise1_a1_count, 'pt_score': pt_score, # 'wpt_score': pt_score * pt_fdist / lpos.dist(pt_apos), 'pt_a01_ratio': pt_a01_ratio, # 'wapt_score': apt_score * apt_fdist / lpos.dist(apt_apos), 'apt_score': apt_score, 'apt_a01_ratio': apt_a01_ratio, # 'noise2_score': noise2_score, 'noise2_a0_count': noise2_a0_count, 'noise2_a1_count': noise2_a1_count, }, { # 'lpos': lpos.to_json(), 'pt_apos': pt_apos, 'pt_idist': lpos.dist(pt_apos), 'pt_yrot': pt_yrot, 'pt_fapos': pt_fapos, 'pt_fdist': pt_fdist, 'apt_apos': apt_apos, 'apt_idist': lpos.dist(apt_apos), 'apt_yrot': apt_yrot, 'apt_fapos': apt_fapos, 'apt_fdist': apt_fdist, 'apt_fyrot': apt_fyrot, })
'apt_fapos': apt_fapos, 'apt_fdist': apt_fdist, 'apt_fyrot': apt_fyrot, }) ############################################################################ def weighted_pt(s, i, f): return s * f / i def weighted_apt(s, i, f): return s * f / i ############################################################################# if __name__ == "__main__": from bncontroller.jsonlib.utils import read_json data = read_json( 'D:\\Xander\\Documenti\\Projects\\BoolNetController\\res\\data\\sim\\handcheck_sim_data_20190730T145525281.json' ) print(sbnc(data, Point3D.from_json({"x": 0.0, "y": 0.3, "z": -0.0})))
def position(self) -> Point3D: return Point3D.from_tuple( tuple(self.supervisor.getSelf().getField('translation').getSFVec3f()) )