Skip to content

Commit 9d22fe5

Browse files
committed
Modified files for visual odom v2
1 parent ddf79e0 commit 9d22fe5

3 files changed

Lines changed: 147 additions & 122 deletions

File tree

exercises/visual_odom/frontend/WebGUI.tsx

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import { states } from "jderobot-commsmanager";
88

99
function WebGUI() {
1010
const exerciseContext = useExercise();
11+
1112
const [image, setImage] = useState<string | undefined>(undefined);
1213

1314
// =========================
14-
// 🧠 NUEVO: POSE STATE
15+
// POSE + TRAJECTORY
1516
// =========================
1617
const [pose, setPose] = useState<any>(null);
18+
const [trajectory, setTrajectory] = useState<any[]>([]);
1719

1820
const [manager, setManager] = useState(exerciseContext.manager);
1921

@@ -26,25 +28,33 @@ function WebGUI() {
2628
const update = data.update;
2729

2830
// =========================
29-
// IMAGE (igual que antes)
31+
// IMAGE
3032
// =========================
3133
if (update.image) {
32-
const image = JSON.parse(update.image);
33-
setImage(`data:image/png;base64,${image.image}`);
34-
35-
// =========================
36-
// 🧠 NUEVO: POSE
37-
// =========================
38-
if (image.pose) {
39-
setPose(image.pose);
40-
}
34+
const img = JSON.parse(update.image);
35+
setImage(`data:image/png;base64,${img.image}`);
36+
}
37+
38+
// =========================
39+
// POSE
40+
// =========================
41+
if (update.pose) {
42+
setPose(update.pose);
43+
}
44+
45+
// =========================
46+
// TRAJECTORY
47+
// =========================
48+
if (update.trajectory) {
49+
setTrajectory(update.trajectory);
4150
}
4251
};
4352

4453
const stateCallback = (state: string) => {
4554
if (state === states.TOOLS_READY) {
4655
setImage(undefined);
4756
setPose(null);
57+
setTrajectory([]);
4858
}
4959
};
5060

@@ -53,11 +63,16 @@ function WebGUI() {
5363
return (
5464
<WebGUIContainer>
5565

56-
{/* Imagen principal (igual que antes) */}
57-
<WebGUIImage id="gui_canvas" src={image} style={{ width: "100%" }} fit />
66+
{/* IMAGE */}
67+
<WebGUIImage
68+
id="gui_canvas"
69+
src={image}
70+
style={{ width: "100%" }}
71+
fit
72+
/>
5873

5974
{/* =========================
60-
🧠 NUEVO: VISOR POSE DEBUG
75+
POSE OVERLAY
6176
========================= */}
6277
{pose && (
6378
<div style={{
@@ -78,6 +93,39 @@ function WebGUI() {
7893
</div>
7994
)}
8095

96+
{/* =========================
97+
TRAJECTORY VISUAL (BÁSICO)
98+
========================= */}
99+
{trajectory.length > 0 && (
100+
<svg
101+
style={{
102+
position: "absolute",
103+
top: 0,
104+
left: 0,
105+
width: "100%",
106+
height: "100%",
107+
pointerEvents: "none",
108+
}}
109+
>
110+
{trajectory.map((p, i) => {
111+
if (i === 0) return null;
112+
const prev = trajectory[i - 1];
113+
114+
return (
115+
<line
116+
key={i}
117+
x1={prev.x * 50 + 200}
118+
y1={prev.y * 50 + 200}
119+
x2={p.x * 50 + 200}
120+
y2={p.y * 50 + 200}
121+
stroke="red"
122+
strokeWidth={2}
123+
/>
124+
);
125+
})}
126+
</svg>
127+
)}
128+
81129
</WebGUIContainer>
82130
);
83131
}

exercises/visual_odom/python_template/HAL.py

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ def __init__(self):
2121
self.bridge = CvBridge()
2222
self.get_logger().info("Input publisher initialized on /input/image_raw")
2323

24+
# =========================================================
25+
# VISUAL ODOMETRY + TRAJECTORY STORAGE
26+
# =========================================================
27+
self.trajectory = [] # list of poses (x, y, z, yaw)
28+
2429
def publish_image(self, cv_image):
2530
"""
2631
Publish a CV image to the ROS2 topic
@@ -49,35 +54,47 @@ def publish_image(self, cv_image):
4954
except Exception as e:
5055
self.get_logger().error(f"Failed to publish image: {e}")
5156

57+
# =========================================================
58+
# VISUAL ODOMETRY API
59+
# =========================================================
5260

53-
# =========================================================
54-
# POSE ESTIMATION (VISUAL ODOMETRY STORAGE)
55-
# =========================================================
56-
57-
_current_pose = {
58-
"x": 0.0,
59-
"y": 0.0,
60-
"z": 0.0,
61-
"roll": 0.0,
62-
"pitch": 0.0,
63-
"yaw": 0.0,
64-
}
65-
66-
67-
def setEstimatedPose(x, y, z=0.0, roll=0.0, pitch=0.0, yaw=0.0):
68-
global _current_pose
69-
_current_pose = {
70-
"x": float(x),
71-
"y": float(y),
72-
"z": float(z),
73-
"roll": float(roll),
74-
"pitch": float(pitch),
75-
"yaw": float(yaw),
76-
}
77-
78-
79-
def getEstimatedPose():
80-
return _current_pose
61+
def setEstimatedPose(self, x, y, z=0.0, roll=0.0, pitch=0.0, yaw=0.0):
62+
"""
63+
Store estimated pose and append to trajectory
64+
"""
65+
pose = {
66+
"x": float(x),
67+
"y": float(y),
68+
"z": float(z),
69+
"roll": float(roll),
70+
"pitch": float(pitch),
71+
"yaw": float(yaw),
72+
}
73+
74+
self._current_pose = pose
75+
self.trajectory.append(pose)
76+
77+
# debug print (NO BORRADO como pediste)
78+
print(f"[HAL] Pose updated: {pose}")
79+
80+
def getEstimatedPose(self):
81+
"""
82+
Return current estimated pose
83+
"""
84+
return getattr(self, "_current_pose", {
85+
"x": 0.0,
86+
"y": 0.0,
87+
"z": 0.0,
88+
"roll": 0.0,
89+
"pitch": 0.0,
90+
"yaw": 0.0,
91+
})
92+
93+
def getTrajectory(self):
94+
"""
95+
Return full trajectory for visualization
96+
"""
97+
return self.trajectory
8198

8299

83100
# =========================================================

0 commit comments

Comments
 (0)