Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -49,6 +49,13 @@ def tau_eff_adaptive(
|
|
| 49 |
gain: float = 1.2,
|
| 50 |
cap: float = 4.0
|
| 51 |
):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
u = clamp(float(uncertainty), 0.0, 1.0)
|
| 53 |
tau = base + slow_by + gain * u
|
| 54 |
return clamp(tau, base, cap)
|
|
@@ -57,6 +64,11 @@ def rft_confidence(uncertainty: float):
|
|
| 57 |
return clamp(1.0 - float(uncertainty), 0.0, 1.0)
|
| 58 |
|
| 59 |
def rft_gate(conf: float, tau_eff: float, threshold: float):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
conf = float(conf)
|
| 61 |
tau_eff = float(tau_eff)
|
| 62 |
effective = threshold + 0.08 * (tau_eff - 1.0)
|
|
@@ -311,6 +323,7 @@ def simulate_landing(
|
|
| 311 |
vv = -45.0
|
| 312 |
x = 60.0
|
| 313 |
xv = 0.0
|
|
|
|
| 314 |
ix = 0.0
|
| 315 |
|
| 316 |
anomalies = 0
|
|
@@ -319,13 +332,11 @@ def simulate_landing(
|
|
| 319 |
rows = []
|
| 320 |
|
| 321 |
g = -9.81
|
|
|
|
| 322 |
LAT_CTRL = 0.95
|
| 323 |
WIND_PUSH = 0.28
|
| 324 |
VERT_CTRL = 0.22
|
| 325 |
|
| 326 |
-
OVERRIDE_X = 18.0
|
| 327 |
-
OVERRIDE_ALT = 260.0
|
| 328 |
-
|
| 329 |
for t in range(int(steps)):
|
| 330 |
gust = math.sin(0.08 * t) + 0.55 * math.sin(0.21 * t + 0.7)
|
| 331 |
wind = (wind_max * 0.75) * gust + np.random.normal(0.0, 0.65)
|
|
@@ -349,7 +360,6 @@ def simulate_landing(
|
|
| 349 |
anomaly_types.append("High lateral error near ground")
|
| 350 |
if meas_alt < 150 and abs(meas_vv) > 15:
|
| 351 |
anomaly_types.append("High descent rate near ground")
|
| 352 |
-
|
| 353 |
is_anomaly = len(anomaly_types) > 0
|
| 354 |
if is_anomaly:
|
| 355 |
anomalies += 1
|
|
@@ -365,9 +375,7 @@ def simulate_landing(
|
|
| 365 |
if meas_alt < 600:
|
| 366 |
ix = clamp(ix + (meas_x * dt) * 0.0025, -40.0, 40.0)
|
| 367 |
|
| 368 |
-
do_action = rft_gate(conf, tau, gate_threshold)
|
| 369 |
-
must_act = (abs(meas_x) > OVERRIDE_X) or (meas_alt < OVERRIDE_ALT)
|
| 370 |
-
do_action = bool(do_action or must_act)
|
| 371 |
|
| 372 |
u_rft_x = 0.0
|
| 373 |
u_rft_v = 0.0
|
|
@@ -466,7 +474,7 @@ def simulate_landing(
|
|
| 466 |
return summary, [p_alt, p_x, p_w, p_a], csv_path
|
| 467 |
|
| 468 |
# ===============================================================
|
| 469 |
-
# Predator Avoidance (Reflex vs
|
| 470 |
# ===============================================================
|
| 471 |
def numpy_convolve2d_toroidal(array: np.ndarray, kernel: np.ndarray) -> np.ndarray:
|
| 472 |
out = np.zeros_like(array, dtype=float)
|
|
@@ -507,7 +515,7 @@ class ReflexAgent:
|
|
| 507 |
self.x = (self.x + dx) % self.grid_size
|
| 508 |
self.y = (self.y + dy) % self.grid_size
|
| 509 |
|
| 510 |
-
class
|
| 511 |
def __init__(
|
| 512 |
self,
|
| 513 |
grid_size: int,
|
|
@@ -544,7 +552,8 @@ class QuantumObserverAgent:
|
|
| 544 |
self.dt_internal = float(dt_internal)
|
| 545 |
self.override_threshold = float(override_threshold)
|
| 546 |
|
| 547 |
-
|
|
|
|
| 548 |
self.overrides = 0
|
| 549 |
self.collisions = 0
|
| 550 |
|
|
@@ -552,6 +561,8 @@ class QuantumObserverAgent:
|
|
| 552 |
dx, dy = random.choice([(0,1), (0,-1), (1,0), (-1,0)])
|
| 553 |
self.x = (self.x + dx) % self.grid_size
|
| 554 |
self.y = (self.y + dy) % self.grid_size
|
|
|
|
|
|
|
| 555 |
self.pos_prob.fill(0.0)
|
| 556 |
self.pos_prob[self.x, self.y] = 1.0
|
| 557 |
|
|
@@ -574,17 +585,25 @@ class QuantumObserverAgent:
|
|
| 574 |
return threat
|
| 575 |
|
| 576 |
def update_override_state(self, perceived):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 577 |
T = self.compute_threat(perceived)
|
| 578 |
E = self.energy / max(self.energy_max, 1e-9)
|
|
|
|
| 579 |
drive = (self.alpha * T) - (self.beta * E)
|
| 580 |
|
|
|
|
| 581 |
exp_term = clamp(drive, -6.0, 6.0) * 0.22 * self.dt_internal
|
| 582 |
amp = math.exp(exp_term)
|
| 583 |
amp = clamp(amp, 0.75, 1.35)
|
| 584 |
|
|
|
|
| 585 |
H = drive + 0.01 * (abs(self.psi_override) ** 2)
|
| 586 |
self.psi_override *= amp * np.exp(-1j * H * self.dt_internal)
|
| 587 |
|
|
|
|
| 588 |
mag = abs(self.psi_override)
|
| 589 |
if mag > 1.0:
|
| 590 |
self.psi_override /= mag
|
|
@@ -636,7 +655,7 @@ class QuantumObserverAgent:
|
|
| 636 |
if self.energy < self.energy_max and random.random() < 0.05:
|
| 637 |
self.energy = self.energy_max
|
| 638 |
|
| 639 |
-
def
|
| 640 |
if self.energy <= 0:
|
| 641 |
self.move()
|
| 642 |
return 0, 0.0, 0.0
|
|
@@ -654,7 +673,7 @@ class QuantumObserverAgent:
|
|
| 654 |
self.overrides += 1
|
| 655 |
self.energy -= effective_cost
|
| 656 |
self.apply_override(perceived)
|
| 657 |
-
self.psi_override = (0.08 + 0j)
|
| 658 |
acted = 1
|
| 659 |
else:
|
| 660 |
self.move()
|
|
@@ -668,7 +687,7 @@ def simulate_predator(
|
|
| 668 |
grid_size: int,
|
| 669 |
steps: int,
|
| 670 |
num_reflex: int,
|
| 671 |
-
|
| 672 |
num_predators: int,
|
| 673 |
group_coherence: float,
|
| 674 |
sense_noise_prob: float,
|
|
@@ -690,8 +709,8 @@ def simulate_predator(
|
|
| 690 |
[0, 0.2, 0]], dtype=float)
|
| 691 |
|
| 692 |
reflex_agents = [ReflexAgent(grid_size) for _ in range(int(num_reflex))]
|
| 693 |
-
|
| 694 |
-
|
| 695 |
grid_size=grid_size,
|
| 696 |
move_kernel=move_kernel,
|
| 697 |
energy_max=energy_max,
|
|
@@ -705,7 +724,7 @@ def simulate_predator(
|
|
| 705 |
dt_internal=dt_internal,
|
| 706 |
override_threshold=override_threshold
|
| 707 |
)
|
| 708 |
-
for _ in range(int(
|
| 709 |
]
|
| 710 |
predators = [Predator(grid_size) for _ in range(int(num_predators))]
|
| 711 |
|
|
@@ -725,8 +744,8 @@ def simulate_predator(
|
|
| 725 |
actions = []
|
| 726 |
povs = []
|
| 727 |
threats = []
|
| 728 |
-
for a in
|
| 729 |
-
acted, P_ov, threat = a.
|
| 730 |
a.regen_energy()
|
| 731 |
actions.append(acted)
|
| 732 |
povs.append(P_ov)
|
|
@@ -738,9 +757,9 @@ def simulate_predator(
|
|
| 738 |
ops_proxy += 18
|
| 739 |
|
| 740 |
reflex_collisions = int(sum(a.collisions for a in reflex_agents))
|
| 741 |
-
|
| 742 |
-
avg_overrides = float(np.mean([a.overrides for a in
|
| 743 |
-
avg_energy = float(np.mean([a.energy for a in
|
| 744 |
avg_threat = float(np.mean(threats)) if threats else 0.0
|
| 745 |
avg_pov = float(np.mean(povs)) if povs else 0.0
|
| 746 |
avg_act = float(np.mean(actions)) if actions else 0.0
|
|
@@ -748,12 +767,12 @@ def simulate_predator(
|
|
| 748 |
rows.append({
|
| 749 |
"t": t,
|
| 750 |
"reflex_collisions_cum": reflex_collisions,
|
| 751 |
-
"
|
| 752 |
-
"
|
| 753 |
-
"
|
| 754 |
-
"
|
| 755 |
-
"
|
| 756 |
-
"
|
| 757 |
"predators_positions": "|".join([f"{p.x},{p.y}" for p in predators]),
|
| 758 |
})
|
| 759 |
|
|
@@ -763,7 +782,7 @@ def simulate_predator(
|
|
| 763 |
fig1 = plt.figure(figsize=(10, 4))
|
| 764 |
ax = fig1.add_subplot(111)
|
| 765 |
ax.plot(df["t"], df["reflex_collisions_cum"], label="Reflex collisions (cum)")
|
| 766 |
-
ax.plot(df["t"], df["
|
| 767 |
ax.set_title("Predator Avoidance: Collisions (Reflex vs RFT)")
|
| 768 |
ax.set_xlabel("t (step)")
|
| 769 |
ax.set_ylabel("collisions (cum)")
|
|
@@ -772,9 +791,9 @@ def simulate_predator(
|
|
| 772 |
|
| 773 |
fig2 = plt.figure(figsize=(10, 4))
|
| 774 |
ax = fig2.add_subplot(111)
|
| 775 |
-
ax.plot(df["t"], df["
|
| 776 |
-
ax.plot(df["t"], df["
|
| 777 |
-
ax.set_title("Predator Avoidance: Overrides + Energy (
|
| 778 |
ax.set_xlabel("t (step)")
|
| 779 |
ax.set_ylabel("value")
|
| 780 |
ax.legend()
|
|
@@ -782,9 +801,9 @@ def simulate_predator(
|
|
| 782 |
|
| 783 |
fig3 = plt.figure(figsize=(10, 4))
|
| 784 |
ax = fig3.add_subplot(111)
|
| 785 |
-
ax.plot(df["t"], df["
|
| 786 |
-
ax.plot(df["t"], df["
|
| 787 |
-
ax.plot(df["t"], df["
|
| 788 |
ax.set_title("Predator Avoidance: Threat vs Override Probability vs Action Rate")
|
| 789 |
ax.set_xlabel("t (step)")
|
| 790 |
ax.set_ylabel("value")
|
|
@@ -792,12 +811,12 @@ def simulate_predator(
|
|
| 792 |
p_thr = save_plot(fig3, f"predator_threat_seed{seed}.png")
|
| 793 |
|
| 794 |
heatmap_path = None
|
| 795 |
-
if show_heatmap and len(
|
| 796 |
-
field =
|
| 797 |
fig4 = plt.figure(figsize=(6, 5))
|
| 798 |
ax = fig4.add_subplot(111)
|
| 799 |
im = ax.imshow(field, aspect="auto")
|
| 800 |
-
ax.set_title("
|
| 801 |
ax.set_xlabel("y")
|
| 802 |
ax.set_ylabel("x")
|
| 803 |
fig4.colorbar(im, ax=ax, fraction=0.046, pad=0.04)
|
|
@@ -808,12 +827,12 @@ def simulate_predator(
|
|
| 808 |
"grid_size": int(grid_size),
|
| 809 |
"steps": int(steps),
|
| 810 |
"num_reflex": int(num_reflex),
|
| 811 |
-
"
|
| 812 |
"num_predators": int(num_predators),
|
| 813 |
"final_reflex_collisions": int(df["reflex_collisions_cum"].iloc[-1]) if len(df) else 0,
|
| 814 |
-
"
|
| 815 |
-
"
|
| 816 |
-
"
|
| 817 |
"ops_proxy": int(ops_proxy),
|
| 818 |
}
|
| 819 |
|
|
@@ -824,7 +843,7 @@ def simulate_predator(
|
|
| 824 |
return summary, imgs, csv_path
|
| 825 |
|
| 826 |
# -----------------------------
|
| 827 |
-
# Benchmarks
|
| 828 |
# -----------------------------
|
| 829 |
def run_benchmarks(
|
| 830 |
seed: int,
|
|
@@ -932,7 +951,7 @@ This Space contains:
|
|
| 932 |
- **NEO alerting**
|
| 933 |
- **Satellite jitter reduction**
|
| 934 |
- **Starship-style landing harness**
|
| 935 |
-
- **Predator avoidance** (Reflex vs RFT-style "
|
| 936 |
|
| 937 |
No SciPy. No hidden dependencies. No model weights.
|
| 938 |
"""
|
|
@@ -1072,7 +1091,7 @@ def ui_run_landing(seed, steps, dt, wind_max, thrust_noise, kp_base, kp_rft, gat
|
|
| 1072 |
summary_txt = json.dumps(summary, indent=2)
|
| 1073 |
return summary_txt, imgs[0], imgs[1], imgs[2], imgs[3], csv_path
|
| 1074 |
|
| 1075 |
-
def ui_run_predator(seed, grid_size, steps, num_reflex,
|
| 1076 |
group_coherence, sense_noise_prob, override_threshold,
|
| 1077 |
alpha, beta, dt_internal,
|
| 1078 |
energy_max, base_override_cost, energy_regen,
|
|
@@ -1083,7 +1102,7 @@ def ui_run_predator(seed, grid_size, steps, num_reflex, num_observer, num_predat
|
|
| 1083 |
grid_size=int(grid_size),
|
| 1084 |
steps=int(steps),
|
| 1085 |
num_reflex=int(num_reflex),
|
| 1086 |
-
|
| 1087 |
num_predators=int(num_predators),
|
| 1088 |
group_coherence=float(group_coherence),
|
| 1089 |
sense_noise_prob=float(sense_noise_prob),
|
|
@@ -1287,7 +1306,7 @@ with gr.Blocks(title="RFT — Agent Console (NEO / Jitter / Landing / Predator)"
|
|
| 1287 |
"# Predator Avoidance (Reflex vs RFT)\n"
|
| 1288 |
"Grid world with roaming predators.\n"
|
| 1289 |
"Reflex agents: random walk.\n"
|
| 1290 |
-
"
|
| 1291 |
)
|
| 1292 |
|
| 1293 |
with gr.Row():
|
|
@@ -1297,7 +1316,7 @@ with gr.Blocks(title="RFT — Agent Console (NEO / Jitter / Landing / Predator)"
|
|
| 1297 |
|
| 1298 |
with gr.Row():
|
| 1299 |
num_reflex = gr.Slider(0, 50, value=10, step=1, label="Reflex agents")
|
| 1300 |
-
|
| 1301 |
num_predators = gr.Slider(1, 20, value=3, step=1, label="Predators")
|
| 1302 |
|
| 1303 |
with gr.Accordion("RFT / Agent parameters", open=True):
|
|
@@ -1334,7 +1353,7 @@ with gr.Blocks(title="RFT — Agent Console (NEO / Jitter / Landing / Predator)"
|
|
| 1334 |
|
| 1335 |
run_p.click(
|
| 1336 |
ui_run_predator,
|
| 1337 |
-
inputs=[seed_p, grid_size, steps_p, num_reflex,
|
| 1338 |
group_coherence, sense_noise_prob, override_threshold,
|
| 1339 |
alpha, beta, dt_internal,
|
| 1340 |
energy_max, base_override_cost, energy_regen,
|
|
|
|
| 49 |
gain: float = 1.2,
|
| 50 |
cap: float = 4.0
|
| 51 |
):
|
| 52 |
+
"""
|
| 53 |
+
τ_eff is implemented here as a timing/decision delay modifier.
|
| 54 |
+
- base: baseline τ_eff
|
| 55 |
+
- slow_by: explicit slow-down term
|
| 56 |
+
- gain: reaction strength to uncertainty
|
| 57 |
+
- cap: prevents absurd values
|
| 58 |
+
"""
|
| 59 |
u = clamp(float(uncertainty), 0.0, 1.0)
|
| 60 |
tau = base + slow_by + gain * u
|
| 61 |
return clamp(tau, base, cap)
|
|
|
|
| 64 |
return clamp(1.0 - float(uncertainty), 0.0, 1.0)
|
| 65 |
|
| 66 |
def rft_gate(conf: float, tau_eff: float, threshold: float):
|
| 67 |
+
"""
|
| 68 |
+
Collapse gate:
|
| 69 |
+
- higher τ_eff makes the gate stricter
|
| 70 |
+
- threshold is the minimum confidence needed
|
| 71 |
+
"""
|
| 72 |
conf = float(conf)
|
| 73 |
tau_eff = float(tau_eff)
|
| 74 |
effective = threshold + 0.08 * (tau_eff - 1.0)
|
|
|
|
| 323 |
vv = -45.0
|
| 324 |
x = 60.0
|
| 325 |
xv = 0.0
|
| 326 |
+
|
| 327 |
ix = 0.0
|
| 328 |
|
| 329 |
anomalies = 0
|
|
|
|
| 332 |
rows = []
|
| 333 |
|
| 334 |
g = -9.81
|
| 335 |
+
|
| 336 |
LAT_CTRL = 0.95
|
| 337 |
WIND_PUSH = 0.28
|
| 338 |
VERT_CTRL = 0.22
|
| 339 |
|
|
|
|
|
|
|
|
|
|
| 340 |
for t in range(int(steps)):
|
| 341 |
gust = math.sin(0.08 * t) + 0.55 * math.sin(0.21 * t + 0.7)
|
| 342 |
wind = (wind_max * 0.75) * gust + np.random.normal(0.0, 0.65)
|
|
|
|
| 360 |
anomaly_types.append("High lateral error near ground")
|
| 361 |
if meas_alt < 150 and abs(meas_vv) > 15:
|
| 362 |
anomaly_types.append("High descent rate near ground")
|
|
|
|
| 363 |
is_anomaly = len(anomaly_types) > 0
|
| 364 |
if is_anomaly:
|
| 365 |
anomalies += 1
|
|
|
|
| 375 |
if meas_alt < 600:
|
| 376 |
ix = clamp(ix + (meas_x * dt) * 0.0025, -40.0, 40.0)
|
| 377 |
|
| 378 |
+
do_action = bool(rft_gate(conf, tau, gate_threshold))
|
|
|
|
|
|
|
| 379 |
|
| 380 |
u_rft_x = 0.0
|
| 381 |
u_rft_v = 0.0
|
|
|
|
| 474 |
return summary, [p_alt, p_x, p_w, p_a], csv_path
|
| 475 |
|
| 476 |
# ===============================================================
|
| 477 |
+
# Predator Avoidance (Reflex vs QuantumConscious "RFT-style")
|
| 478 |
# ===============================================================
|
| 479 |
def numpy_convolve2d_toroidal(array: np.ndarray, kernel: np.ndarray) -> np.ndarray:
|
| 480 |
out = np.zeros_like(array, dtype=float)
|
|
|
|
| 515 |
self.x = (self.x + dx) % self.grid_size
|
| 516 |
self.y = (self.y + dy) % self.grid_size
|
| 517 |
|
| 518 |
+
class QuantumConsciousAgent:
|
| 519 |
def __init__(
|
| 520 |
self,
|
| 521 |
grid_size: int,
|
|
|
|
| 552 |
self.dt_internal = float(dt_internal)
|
| 553 |
self.override_threshold = float(override_threshold)
|
| 554 |
|
| 555 |
+
# Start low so P_override is not pinned at the threshold.
|
| 556 |
+
self.psi_override = (0.08 + 0j) # |psi|^2 = 0.0064
|
| 557 |
self.overrides = 0
|
| 558 |
self.collisions = 0
|
| 559 |
|
|
|
|
| 561 |
dx, dy = random.choice([(0,1), (0,-1), (1,0), (-1,0)])
|
| 562 |
self.x = (self.x + dx) % self.grid_size
|
| 563 |
self.y = (self.y + dy) % self.grid_size
|
| 564 |
+
|
| 565 |
+
# Keep pos_prob consistent with actual state (otherwise threat stays meaningless)
|
| 566 |
self.pos_prob.fill(0.0)
|
| 567 |
self.pos_prob[self.x, self.y] = 1.0
|
| 568 |
|
|
|
|
| 585 |
return threat
|
| 586 |
|
| 587 |
def update_override_state(self, perceived):
|
| 588 |
+
"""
|
| 589 |
+
Make P_override responsive (amplitude changes), not phase-only.
|
| 590 |
+
Threat pushes amplitude up; energy pushes it down.
|
| 591 |
+
"""
|
| 592 |
T = self.compute_threat(perceived)
|
| 593 |
E = self.energy / max(self.energy_max, 1e-9)
|
| 594 |
+
|
| 595 |
drive = (self.alpha * T) - (self.beta * E)
|
| 596 |
|
| 597 |
+
# amplitude pump/decay (bounded)
|
| 598 |
exp_term = clamp(drive, -6.0, 6.0) * 0.22 * self.dt_internal
|
| 599 |
amp = math.exp(exp_term)
|
| 600 |
amp = clamp(amp, 0.75, 1.35)
|
| 601 |
|
| 602 |
+
# keep a "quantum-style" phase evolution too
|
| 603 |
H = drive + 0.01 * (abs(self.psi_override) ** 2)
|
| 604 |
self.psi_override *= amp * np.exp(-1j * H * self.dt_internal)
|
| 605 |
|
| 606 |
+
# cap magnitude so probability stays within [0,1]
|
| 607 |
mag = abs(self.psi_override)
|
| 608 |
if mag > 1.0:
|
| 609 |
self.psi_override /= mag
|
|
|
|
| 655 |
if self.energy < self.energy_max and random.random() < 0.05:
|
| 656 |
self.energy = self.energy_max
|
| 657 |
|
| 658 |
+
def move_consciously(self, predators, group_coherence: float):
|
| 659 |
if self.energy <= 0:
|
| 660 |
self.move()
|
| 661 |
return 0, 0.0, 0.0
|
|
|
|
| 673 |
self.overrides += 1
|
| 674 |
self.energy -= effective_cost
|
| 675 |
self.apply_override(perceived)
|
| 676 |
+
self.psi_override = (0.08 + 0j) # reset after a collapse action
|
| 677 |
acted = 1
|
| 678 |
else:
|
| 679 |
self.move()
|
|
|
|
| 687 |
grid_size: int,
|
| 688 |
steps: int,
|
| 689 |
num_reflex: int,
|
| 690 |
+
num_conscious: int,
|
| 691 |
num_predators: int,
|
| 692 |
group_coherence: float,
|
| 693 |
sense_noise_prob: float,
|
|
|
|
| 709 |
[0, 0.2, 0]], dtype=float)
|
| 710 |
|
| 711 |
reflex_agents = [ReflexAgent(grid_size) for _ in range(int(num_reflex))]
|
| 712 |
+
conscious_agents = [
|
| 713 |
+
QuantumConsciousAgent(
|
| 714 |
grid_size=grid_size,
|
| 715 |
move_kernel=move_kernel,
|
| 716 |
energy_max=energy_max,
|
|
|
|
| 724 |
dt_internal=dt_internal,
|
| 725 |
override_threshold=override_threshold
|
| 726 |
)
|
| 727 |
+
for _ in range(int(num_conscious))
|
| 728 |
]
|
| 729 |
predators = [Predator(grid_size) for _ in range(int(num_predators))]
|
| 730 |
|
|
|
|
| 744 |
actions = []
|
| 745 |
povs = []
|
| 746 |
threats = []
|
| 747 |
+
for a in conscious_agents:
|
| 748 |
+
acted, P_ov, threat = a.move_consciously(predators, group_coherence)
|
| 749 |
a.regen_energy()
|
| 750 |
actions.append(acted)
|
| 751 |
povs.append(P_ov)
|
|
|
|
| 757 |
ops_proxy += 18
|
| 758 |
|
| 759 |
reflex_collisions = int(sum(a.collisions for a in reflex_agents))
|
| 760 |
+
conscious_collisions = int(sum(a.collisions for a in conscious_agents))
|
| 761 |
+
avg_overrides = float(np.mean([a.overrides for a in conscious_agents])) if conscious_agents else 0.0
|
| 762 |
+
avg_energy = float(np.mean([a.energy for a in conscious_agents])) if conscious_agents else 0.0
|
| 763 |
avg_threat = float(np.mean(threats)) if threats else 0.0
|
| 764 |
avg_pov = float(np.mean(povs)) if povs else 0.0
|
| 765 |
avg_act = float(np.mean(actions)) if actions else 0.0
|
|
|
|
| 767 |
rows.append({
|
| 768 |
"t": t,
|
| 769 |
"reflex_collisions_cum": reflex_collisions,
|
| 770 |
+
"conscious_collisions_cum": conscious_collisions,
|
| 771 |
+
"avg_conscious_overrides": avg_overrides,
|
| 772 |
+
"avg_conscious_energy": avg_energy,
|
| 773 |
+
"avg_conscious_threat": avg_threat,
|
| 774 |
+
"avg_conscious_P_override": avg_pov,
|
| 775 |
+
"avg_conscious_action": avg_act,
|
| 776 |
"predators_positions": "|".join([f"{p.x},{p.y}" for p in predators]),
|
| 777 |
})
|
| 778 |
|
|
|
|
| 782 |
fig1 = plt.figure(figsize=(10, 4))
|
| 783 |
ax = fig1.add_subplot(111)
|
| 784 |
ax.plot(df["t"], df["reflex_collisions_cum"], label="Reflex collisions (cum)")
|
| 785 |
+
ax.plot(df["t"], df["conscious_collisions_cum"], label="Conscious collisions (cum)")
|
| 786 |
ax.set_title("Predator Avoidance: Collisions (Reflex vs RFT)")
|
| 787 |
ax.set_xlabel("t (step)")
|
| 788 |
ax.set_ylabel("collisions (cum)")
|
|
|
|
| 791 |
|
| 792 |
fig2 = plt.figure(figsize=(10, 4))
|
| 793 |
ax = fig2.add_subplot(111)
|
| 794 |
+
ax.plot(df["t"], df["avg_conscious_overrides"], label="Avg overrides (conscious)")
|
| 795 |
+
ax.plot(df["t"], df["avg_conscious_energy"], label="Avg energy (conscious)")
|
| 796 |
+
ax.set_title("Predator Avoidance: Overrides + Energy (Conscious)")
|
| 797 |
ax.set_xlabel("t (step)")
|
| 798 |
ax.set_ylabel("value")
|
| 799 |
ax.legend()
|
|
|
|
| 801 |
|
| 802 |
fig3 = plt.figure(figsize=(10, 4))
|
| 803 |
ax = fig3.add_subplot(111)
|
| 804 |
+
ax.plot(df["t"], df["avg_conscious_threat"], label="Avg threat")
|
| 805 |
+
ax.plot(df["t"], df["avg_conscious_P_override"], label="Avg P_override")
|
| 806 |
+
ax.plot(df["t"], df["avg_conscious_action"], label="Avg action rate")
|
| 807 |
ax.set_title("Predator Avoidance: Threat vs Override Probability vs Action Rate")
|
| 808 |
ax.set_xlabel("t (step)")
|
| 809 |
ax.set_ylabel("value")
|
|
|
|
| 811 |
p_thr = save_plot(fig3, f"predator_threat_seed{seed}.png")
|
| 812 |
|
| 813 |
heatmap_path = None
|
| 814 |
+
if show_heatmap and len(conscious_agents) > 0:
|
| 815 |
+
field = conscious_agents[0].pos_prob
|
| 816 |
fig4 = plt.figure(figsize=(6, 5))
|
| 817 |
ax = fig4.add_subplot(111)
|
| 818 |
im = ax.imshow(field, aspect="auto")
|
| 819 |
+
ax.set_title("Conscious Agent[0]: Final probability field (pos_prob)")
|
| 820 |
ax.set_xlabel("y")
|
| 821 |
ax.set_ylabel("x")
|
| 822 |
fig4.colorbar(im, ax=ax, fraction=0.046, pad=0.04)
|
|
|
|
| 827 |
"grid_size": int(grid_size),
|
| 828 |
"steps": int(steps),
|
| 829 |
"num_reflex": int(num_reflex),
|
| 830 |
+
"num_conscious": int(num_conscious),
|
| 831 |
"num_predators": int(num_predators),
|
| 832 |
"final_reflex_collisions": int(df["reflex_collisions_cum"].iloc[-1]) if len(df) else 0,
|
| 833 |
+
"final_conscious_collisions": int(df["conscious_collisions_cum"].iloc[-1]) if len(df) else 0,
|
| 834 |
+
"final_avg_conscious_overrides": float(df["avg_conscious_overrides"].iloc[-1]) if len(df) else 0.0,
|
| 835 |
+
"final_avg_conscious_energy": float(df["avg_conscious_energy"].iloc[-1]) if len(df) else 0.0,
|
| 836 |
"ops_proxy": int(ops_proxy),
|
| 837 |
}
|
| 838 |
|
|
|
|
| 843 |
return summary, imgs, csv_path
|
| 844 |
|
| 845 |
# -----------------------------
|
| 846 |
+
# Benchmarks
|
| 847 |
# -----------------------------
|
| 848 |
def run_benchmarks(
|
| 849 |
seed: int,
|
|
|
|
| 951 |
- **NEO alerting**
|
| 952 |
- **Satellite jitter reduction**
|
| 953 |
- **Starship-style landing harness**
|
| 954 |
+
- **Predator avoidance** (Reflex vs RFT-style "QuantumConscious" agents)
|
| 955 |
|
| 956 |
No SciPy. No hidden dependencies. No model weights.
|
| 957 |
"""
|
|
|
|
| 1091 |
summary_txt = json.dumps(summary, indent=2)
|
| 1092 |
return summary_txt, imgs[0], imgs[1], imgs[2], imgs[3], csv_path
|
| 1093 |
|
| 1094 |
+
def ui_run_predator(seed, grid_size, steps, num_reflex, num_conscious, num_predators,
|
| 1095 |
group_coherence, sense_noise_prob, override_threshold,
|
| 1096 |
alpha, beta, dt_internal,
|
| 1097 |
energy_max, base_override_cost, energy_regen,
|
|
|
|
| 1102 |
grid_size=int(grid_size),
|
| 1103 |
steps=int(steps),
|
| 1104 |
num_reflex=int(num_reflex),
|
| 1105 |
+
num_conscious=int(num_conscious),
|
| 1106 |
num_predators=int(num_predators),
|
| 1107 |
group_coherence=float(group_coherence),
|
| 1108 |
sense_noise_prob=float(sense_noise_prob),
|
|
|
|
| 1306 |
"# Predator Avoidance (Reflex vs RFT)\n"
|
| 1307 |
"Grid world with roaming predators.\n"
|
| 1308 |
"Reflex agents: random walk.\n"
|
| 1309 |
+
"Conscious agents: probability field + threat-weighted override.\n"
|
| 1310 |
)
|
| 1311 |
|
| 1312 |
with gr.Row():
|
|
|
|
| 1316 |
|
| 1317 |
with gr.Row():
|
| 1318 |
num_reflex = gr.Slider(0, 50, value=10, step=1, label="Reflex agents")
|
| 1319 |
+
num_conscious = gr.Slider(0, 20, value=3, step=1, label="Conscious agents")
|
| 1320 |
num_predators = gr.Slider(1, 20, value=3, step=1, label="Predators")
|
| 1321 |
|
| 1322 |
with gr.Accordion("RFT / Agent parameters", open=True):
|
|
|
|
| 1353 |
|
| 1354 |
run_p.click(
|
| 1355 |
ui_run_predator,
|
| 1356 |
+
inputs=[seed_p, grid_size, steps_p, num_reflex, num_conscious, num_predators,
|
| 1357 |
group_coherence, sense_noise_prob, override_threshold,
|
| 1358 |
alpha, beta, dt_internal,
|
| 1359 |
energy_max, base_override_cost, energy_regen,
|