import numpy as np from scipy.integrate import solve_ivp from gausse.physics.sensors import make_inductive_sensor_event, make_optical_sensor_event def _ballistic(t, state): return [state[1], 0.0] def test_optical_sensor_trigger_is_velocity_independent(): x_sensor = 0.02 trigger_xs = [] for v in (1.0, 5.0, 20.0): event = make_optical_sensor_event(x_sensor) sol = solve_ivp(_ballistic, (0, 1.0), [-0.05, v], events=event) assert len(sol.t_events[0]) == 1 trigger_xs.append(sol.y_events[0][0][0]) assert np.allclose(trigger_xs, x_sensor, atol=1e-9) def test_inductive_sensor_fires_earlier_at_higher_velocity(): x_sensor = 0.02 sensitivity = 0.05 threshold = 0.3 width = 0.005 trigger_xs = [] for v in (10.0, 20.0, 40.0): event = make_inductive_sensor_event(x_sensor, sensitivity, threshold, width) sol = solve_ivp(_ballistic, (0, 1.0), [-0.05, v], events=event) assert len(sol.t_events[0]) == 1 trigger_xs.append(sol.y_events[0][0][0]) # чем выше скорость, тем раньше (дальше от датчика, т.е. при меньшем x) # срабатывает индукционный датчик, т.к. sensitivity*v*bump(x) достигает # порога при меньшем bump(x), а значит при большем |x - x_sensor| assert trigger_xs[0] > trigger_xs[1] > trigger_xs[2] assert all(x < x_sensor for x in trigger_xs) def test_inductive_sensor_never_fires_below_threshold_speed(): x_sensor = 0.02 sensitivity = 0.05 threshold = 0.3 width = 0.005 # пиковый сигнал = sensitivity * v = 0.05 * 1.0 = 0.05 << порог 0.3 event = make_inductive_sensor_event(x_sensor, sensitivity, threshold, width) sol = solve_ivp(_ballistic, (0, 1.0), [-0.05, 1.0], events=event) assert len(sol.t_events[0]) == 0