Skip to content

Commit b41fb3d

Browse files
committed
analysis
1 parent 2625dbc commit b41fb3d

File tree

9 files changed

+168
-60
lines changed

9 files changed

+168
-60
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.vscode/settings.json
12
proj/secrets.py
23

34
.vscode/*

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"python.pythonPath": "/Users/federicoclaudi/miniconda3/envs/dev/bin/python",
2+
"python.pythonPath": "C:\\Users\\Federico\\.conda\\envs\\dev\\python.exe",
33
"cSpell.enabled": true
44
}

analysis/__init__py

Whitespace-only changes.

analysis/utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def check_two_conf_equal(c1, c2):
2+
for key, val in c1.items():
3+
if c2[key] != val:
4+
return False
5+
6+
return True

proj/environment/plotter.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def make_figure(self):
2626

2727
self.f = plt.figure(figsize=(16, 8))
2828

29-
gs = self.f.add_gridspec(2, 6)
29+
gs = self.f.add_gridspec(2, 3) # 6)
3030
self.xy_ax = self.f.add_subplot(gs[:, :2])
3131
self.xy_ax.axis("equal")
3232
self.xy_ax.axis("off")
@@ -35,11 +35,11 @@ def make_figure(self):
3535

3636
self.sax = self.f.add_subplot(gs[1, 2:4])
3737

38-
self.accel_ax = self.f.add_subplot(gs[0, 4])
38+
# self.accel_ax = self.f.add_subplot(gs[0, 4])
3939

40-
self.goal_ax = self.f.add_subplot(gs[0, 5])
40+
# self.goal_ax = self.f.add_subplot(gs[0, 5])
4141

42-
self.cost_ax = self.f.add_subplot(gs[1, 4:])
42+
# self.cost_ax = self.f.add_subplot(gs[1, 4:])
4343

4444
clean_axes(self.f)
4545

@@ -316,17 +316,17 @@ def visualize_world_live(self, curr_goals, elapsed=None):
316316
# plot control
317317
self._plot_control()
318318

319-
# plot current waypoint
319+
# plot sped
320320
self._plot_current_variables()
321321

322-
# plot accelerations
323-
self._plot_accelerations()
322+
# # plot accelerations
323+
# self._plot_accelerations()
324324

325-
# plot cost
326-
self._plot_cost()
325+
# # plot cost
326+
# self._plot_cost()
327327

328-
# plot goal
329-
self._plot_goal(curr_goals[0, :])
328+
# # plot goal
329+
# self._plot_goal(curr_goals[0, :])
330330

331331
# display plot
332332
self.f.canvas.draw()

proj/environment/trajectories.py

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ def complete_given_xy(x, y, params, planning_params):
4343

4444

4545
def compute_trajectory_stats(
46-
trajectory, duration, params, planning_params, min_dist_travelled=150
46+
trajectory,
47+
duration,
48+
params,
49+
planning_params,
50+
min_dist_travelled=150,
51+
mute=False,
4752
):
4853
# Compute stats
4954
n_points = len(trajectory)
@@ -85,46 +90,59 @@ def compute_trajectory_stats(
8590
)
8691

8792
# log stuff
88-
logger.info(
89-
f"""
90-
Trajectory metadata
91-
92-
93-
n_points = {n_points}
94-
distance_travelled = {round(distance_travelled, 2)}
95-
waypoint_density = {round(waypoint_density, 2)}
96-
start_goal_distance = {round(start_goal_distance, 2)}
97-
duration = {round(duration, 2)}
98-
lookahead = {lookahead}
99-
perc_lookahead = {perc_lookahead}
100-
"""
101-
)
102-
print(table)
103-
104-
if waypoint_density < 2 or waypoint_density > 3:
93+
if not mute:
10594
logger.info(
106-
f"Waypoint density of {round(waypoint_density, 3)} out of range, it should be 2 < wp < 3!",
107-
extra={"markdown": True},
108-
)
109-
print(
110-
f"[bold red]Waypoint density of {round(waypoint_density, 3)} out of range, it should be 2 < wp < 3!"
95+
f"""
96+
Trajectory metadata
97+
98+
99+
n_points = {n_points}
100+
distance_travelled = {round(distance_travelled, 2)}
101+
waypoint_density = {round(waypoint_density, 2)}
102+
start_goal_distance = {round(start_goal_distance, 2)}
103+
duration = {round(duration, 2)}
104+
lookahead = {lookahead}
105+
perc_lookahead = {perc_lookahead}
106+
"""
111107
)
112108

113-
if perc_lookahead < 0.05:
114-
logger.info(
115-
f"Lookahead of {lookahead} is {perc_lookahead} of the # of waypoints, that might be too low. Values closer to 5% are advised.",
116-
extra={"markdown": True},
117-
)
118-
print(
119-
f"[bold red]Lookahead of {lookahead} is {perc_lookahead} of the # of waypoints, that might be too low. Values closer to 5% are advised."
120-
)
121-
if distance_travelled < min_dist_travelled * params["px_to_cm"]:
122-
logger.warning(
123-
"Distance travelled below minimal requirement, erroring"
124-
)
125-
return None, None
109+
print(table)
126110

127-
return trajectory, duration
111+
metadata = dict(
112+
n_points=n_points,
113+
distance_travelled=round(distance_travelled, 2),
114+
waypoint_density=round(waypoint_density, 2),
115+
start_goal_distance=round(start_goal_distance, 2),
116+
duration=round(duration, 2),
117+
lookahead=lookahead,
118+
perc_lookahead=perc_lookahead,
119+
)
120+
121+
if not mute:
122+
if waypoint_density < 2 or waypoint_density > 3:
123+
logger.info(
124+
f"Waypoint density of {round(waypoint_density, 3)} out of range, it should be 2 < wp < 3!",
125+
extra={"markdown": True},
126+
)
127+
print(
128+
f"[bold red]Waypoint density of {round(waypoint_density, 3)} out of range, it should be 2 < wp < 3!"
129+
)
130+
131+
if perc_lookahead < 0.05:
132+
logger.info(
133+
f"Lookahead of {lookahead} is {perc_lookahead} of the # of waypoints, that might be too low. Values closer to 5% are advised.",
134+
extra={"markdown": True},
135+
)
136+
print(
137+
f"[bold red]Lookahead of {lookahead} is {perc_lookahead} of the # of waypoints, that might be too low. Values closer to 5% are advised."
138+
)
139+
if distance_travelled < min_dist_travelled * params["px_to_cm"]:
140+
logger.warning(
141+
"Distance travelled below minimal requirement, erroring"
142+
)
143+
return None, None
144+
145+
return trajectory, duration, metadata
128146

129147

130148
# ---------------------------------- Curves ---------------------------------- #
@@ -253,6 +271,6 @@ def from_tracking(n_steps, params, planning_params, cache_fld, *args):
253271
return (
254272
compute_trajectory_stats(
255273
trajectory, len(x[start:]) / fps, params, planning_params
256-
),
274+
)[:2],
257275
trials,
258276
)

proj/model/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class Config:
5252

5353
USE_FAST = True # if true use cumba's methods
5454
SPAWN_TYPE = "trajectory"
55-
LIVE_PLOT = False
55+
LIVE_PLOT = True
5656

5757
mouse_type = "easy"
5858
model_type = "cart"

proj/paths.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
db_app = "D:\\Dropbox (UCL - SWC)\\Apps\\loco_upload"
2828

29+
30+
analysis_fld = str(Path(main_fld) / "analysis")
31+
2932
# winstor paths
3033
winstor_main = Path("/nfs/winstor/branco/Federico/Locomotion/control/data")
3134
winstor_trial_cache = (

workspace.py

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,93 @@
1-
from proj import Model
2-
from rich import print
3-
from sympy import latex
4-
from pylatexenc.latex2text import LatexNodes2Text
1+
# %%
2+
from pathlib import Path
3+
from rich.progress import track
4+
import numpy as np
5+
import pyinspect as pi
6+
import matplotlib.pyplot as plt
7+
import shutil
58

6-
model = Model()
7-
model.get_combined_dynamics_kinematics()
9+
from fcutils.maths.geometry import calc_distance_between_points_in_a_vector_2d
810

9-
g, inp, M = model.matrixes["g"], model.matrixes["inp"], model.matrixes["M"]
11+
from proj.paths import analysis_fld, db_app
12+
from proj.utils.misc import load_results_from_folder
13+
from proj.environment.trajectories import compute_trajectory_stats
1014

11-
mod = g + M * inp
15+
from analysis.utils import check_two_conf_equal
1216

13-
print(LatexNodes2Text().latex_to_text((latex(inp))))
17+
# %%
18+
# Load all data in DB upload folder
19+
flds = [f for f in Path(db_app).glob("*") if f.is_dir()]
20+
21+
22+
loaded = dict(trajectory=[], history=[], cost_history=[],)
23+
24+
config = None
25+
26+
for fld in track(flds):
27+
_config, trajectory, history, cost_history = load_results_from_folder(fld)
28+
29+
# Check that all data have the same config
30+
if config is None:
31+
config = _config
32+
else:
33+
if not check_two_conf_equal(config, _config):
34+
raise ValueError("Not all simulations have the same config")
35+
36+
# stash
37+
loaded["trajectory"].append(trajectory)
38+
loaded["history"].append(history)
39+
loaded["cost_history"].append(cost_history)
40+
41+
42+
pi.ok("Data loaded")
43+
44+
# %%
45+
# Copy all outcome plots in same folder
46+
outcomes_fld = Path(analysis_fld) / "outcomes"
47+
outcomes_fld.mkdir(exist_ok=True)
48+
49+
for fld in track(flds):
50+
src = list(fld.glob("outcome.png"))[0]
51+
dst = outcomes_fld / (src.parent.name + "_outcome.png")
52+
53+
shutil.copy(src, dst)
54+
55+
pi.ok("All outcome images copied", str(outcomes_fld))
56+
57+
# %%
58+
"""
59+
Look at trajectory length vs distance travelled
60+
"""
61+
62+
traj_dist = []
63+
actual_dist = []
64+
65+
for traj, hist in track(
66+
zip(loaded["trajectory"], loaded["history"]),
67+
total=len(loaded["trajectory"]),
68+
):
69+
metad = compute_trajectory_stats(
70+
traj, 1, config["trajectory"], config["planning"], mute=True
71+
)[-1]
72+
traj_dist.append(metad["distance_travelled"])
73+
74+
actual_dist.append(
75+
np.sum(calc_distance_between_points_in_a_vector_2d(hist.x, hist.y))
76+
+ config["trajectory"]["dist_th"]
77+
)
78+
79+
# %%
80+
f, ax = plt.subplots(figsize=(12, 12))
81+
ax.scatter(
82+
traj_dist,
83+
actual_dist,
84+
s=100,
85+
color="g",
86+
alpha=0.4,
87+
lw=1,
88+
ec=[0.3, 0.3, 0.3],
89+
)
90+
ax.plot([400, 1000], [400, 1000], lw=2, color=[0.6, 0.6, 0.6], zorder=-1)
91+
92+
ax.set(xlabel="Trajectory length", ylabel="Distance travelled")
93+
# %%

0 commit comments

Comments
 (0)