Skip to content

Commit 9f736bc

Browse files
Merge branch 's2025_teamA' into EstCal_A
merging team a main to local
2 parents 88bdc23 + 6f4aa44 commit 9f736bc

6 files changed

Lines changed: 108 additions & 26 deletions

File tree

.github/workflows/python-app.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# This workflow will install Python dependencies, run tests and lint with a single version of Python
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3+
4+
name: Python application
5+
6+
on:
7+
push:
8+
branches:
9+
- '**'
10+
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
PEP-Guidelines:
17+
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- uses: actions/checkout@v3
22+
- name: Set up Python 3.10
23+
uses: actions/setup-python@v3
24+
with:
25+
python-version: "3.10"
26+
- name: Install dependencies
27+
run: |
28+
python -m pip install --upgrade pip
29+
pip install flake8 flake8-docstrings pep8-naming
30+
- name: Lint with flake8
31+
run: |
32+
# stop the build if there are Python syntax errors or undefined names
33+
flake8 ./GEMstack --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=__init__.py || exit 1
34+
# to enable more advanced checks on the repo, uncomment the lines below (There are around 3000 violations)
35+
# flake8 ./GEMstack --ignore=D,C901,E402,E231 --count --max-complexity=10 --max-line-length=127 --statistics --exclude=__init__.py || exit 1
36+
# if we want to enable documentation checks, uncomment the line below
37+
# flake8 ./GEMstack --ignore=E128,E402,E501,F401 --docstring-convention pep257 --max-line-length=120 --exclude=__init__.py || exit 1
38+
continue-on-error: false
39+
40+
Documentation:
41+
42+
runs-on: ubuntu-latest
43+
44+
steps:
45+
- uses: actions/checkout@v3
46+
- name: Set up Python 3.10
47+
uses: actions/setup-python@v3
48+
with:
49+
python-version: "3.10"
50+
- name: Install dependencies
51+
run: |
52+
python -m pip install --upgrade pip
53+
pip install sphinx sphinx-rtd-theme
54+
- name: Generate Documentation
55+
run: |
56+
# stop the build if there are Python syntax errors or undefined names
57+
sphinx-build -b html docs docs/build
58+
- name: Save Documentation as Artifact
59+
uses: actions/upload-artifact@v4
60+
with:
61+
name: documentation
62+
path: docs/build

GEMstack/onboard/visualization/klampt_visualization.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from ..component import Component
2+
from klampt import __version__ as klampt_version
23
from klampt import vis
34
from klampt.math import se3
45
from klampt import *
@@ -11,14 +12,16 @@
1112
import numpy as np
1213

1314
class KlamptVisualization(Component):
14-
"""Runs a matplotlib visualization at 10Hz.
15-
16-
If save_as is not None, saves the visualization to a file.
15+
"""Runs a Klampt visualization.
16+
17+
Runs at 20Hz by default.
1718
"""
1819
def __init__(self, vehicle_interface, rate : float = 20.0, save_as : str = None):
1920
self.vehicle_interface = vehicle_interface
2021
self._rate = rate
2122
self.save_as = save_as
23+
if save_as is not None:
24+
print("WARNING: automatic saving of KlamptVisualization to movie is not supported yet. You can use Ctrl+M to start / stop saving the movie")
2225
self.num_updates = 0
2326
self.last_yaw = None
2427
self.plot_values = {}
@@ -57,12 +60,20 @@ def state_inputs(self):
5760
def initialize(self):
5861
vis.setWindowTitle("GEMstack visualization")
5962
vp = vis.getViewport()
60-
vp.camera.rot[1] = -0.15
61-
vp.camera.rot[2] = -math.pi/2
62-
vp.camera.dist = 30.0
63-
vp.w = 1280
64-
vp.h = 720
65-
vp.clippingplanes = (0.1,1000)
63+
if klampt_version == '0.10.0':
64+
vp.controller.rot[1] = -0.15
65+
vp.controller.rot[2] = -math.pi/2
66+
vp.controller.dist = 30.0
67+
vp.resize(1280,720)
68+
vp.n = 0.1
69+
vp.f = 1000
70+
else:
71+
vp.camera.rot[1] = -0.15
72+
vp.camera.rot[2] = -math.pi/2
73+
vp.camera.dist = 30.0
74+
vp.w = 1280
75+
vp.h = 720
76+
vp.clippingplanes = (0.1,1000)
6677
vis.setViewport(vp)
6778
vis.add("vehicle_plane",self.world.terrain(0),hide_label=True)
6879
#note: show() takes over the interrupt handler and sets it to default, so we restore it
@@ -121,9 +132,14 @@ def update(self, state):
121132
center_offset = 1.0
122133
lookahead = 4.0*v
123134
dx,dy = math.cos(tracked_vehicle.pose.yaw)*(lookahead+center_offset),math.sin(tracked_vehicle.pose.yaw)*(lookahead+center_offset)
124-
vp.camera.tgt = [tracked_vehicle.pose.x+dx,tracked_vehicle.pose.y+dy,1.5]
125-
vp.camera.rot[2] += tracked_vehicle.pose.yaw - self.last_yaw
126-
vp.camera.dist += 5.0*(v - self.last_v)
135+
if klampt_version == '0.10.0':
136+
vp.controller.tgt = [tracked_vehicle.pose.x+dx,tracked_vehicle.pose.y+dy,1.5]
137+
vp.controller.rot[2] += tracked_vehicle.pose.yaw - self.last_yaw
138+
vp.controller.dist += 5.0*(v - self.last_v)
139+
else:
140+
vp.camera.tgt = [tracked_vehicle.pose.x+dx,tracked_vehicle.pose.y+dy,1.5]
141+
vp.camera.rot[2] += tracked_vehicle.pose.yaw - self.last_yaw
142+
vp.camera.dist += 5.0*(v - self.last_v)
127143
self.last_v = v
128144
vis.setViewport(vp)
129145

GEMstack/utils/config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def save_config(fn : str, config : dict) -> None:
1818

1919

2020
def load_config_recursive(fn : str) -> dict:
21-
"""Loads a configuration file with !include directives."""
21+
"""Loads a configuration file with !include and !relative_path directives."""
2222
if fn.endswith('yaml') or fn.endswith('yml'):
2323
with open(fn,'r') as f:
2424
res = yaml.load(f,_Loader)
@@ -35,7 +35,7 @@ def load_config_recursive(fn : str) -> dict:
3535

3636

3737
class _Loader(yaml.SafeLoader):
38-
"""YAML Loader with `!include` constructor."""
38+
"""YAML Loader with `!include` and `!relative_path` directives."""
3939

4040
def __init__(self, stream: IO) -> None:
4141
"""Initialise Loader."""
@@ -60,7 +60,7 @@ def _construct_relative_path(loader: _Loader, node: yaml.Node) -> Any:
6060
yaml.add_constructor('!relative_path', _construct_relative_path, _Loader)
6161

6262
def _load_config_or_text_recursive(fn : str) -> dict:
63-
"""Loads a configuration file with !include directives."""
63+
"""Loads a configuration file with !include and !relative_path directives."""
6464
if fn.endswith('yaml') or fn.endswith('yml'):
6565
with open(fn,'r') as f:
6666
res = yaml.load(f,_Loader)

GEMstack/utils/klampt_visualization.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
from . import settings
77
from ..state import ObjectFrameEnum,ObjectPose,PhysicalObject,VehicleState,VehicleGearEnum,Path,Obstacle,AgentState,AgentEnum,Roadgraph,RoadgraphLane,RoadgraphLaneEnum,RoadgraphCurve,RoadgraphCurveEnum,RoadgraphRegion,RoadgraphRegionEnum,RoadgraphSurfaceEnum,Trajectory,Route,SceneState,AllState
88

9+
#KH: there is a bug on some system where the visualization crashes with an OpenGL error when drawing curves
10+
#this is a workaround. We really should find the source of the bug!
11+
MAX_POINTS_IN_CURVE = 50
12+
913
OBJECT_COLORS = {
1014
AgentEnum.CAR : (1,1,0,1),
1115
AgentEnum.PEDESTRIAN : (0,1,0,1),
@@ -198,8 +202,8 @@ def plot_vehicle(vehicle : VehicleState, vehicle_model=None, axis_len=1.0):
198202
vehicle_model.link('rear_left_stop_light_link').appearance().setColor(0.3,0,0,1)
199203

200204
def plot_path(name : str, path : Path, color=(0,0,0), width=1):
201-
if len(path.points) > 50:
202-
vis.add(name,[list(p) for p in path.points[::len(path.points)//50]],color=color,width=width)
205+
if len(path.points) > MAX_POINTS_IN_CURVE: # downsample due to OpenGL error?
206+
vis.add(name,[list(p) for p in path.points[::len(path.points)//MAX_POINTS_IN_CURVE]],color=color,width=width)
203207
else:
204208
vis.add(name,[list(p) for p in path.points],color=color,width=width)
205209

@@ -214,8 +218,8 @@ def plot_curve(name : str, curve : RoadgraphCurve, color=None, width=None):
214218
if width is not None:
215219
style['width'] = width
216220
for i,seg in enumerate(curve.segments):
217-
if len(seg) > 50:
218-
vis.add(name+"_%d" % i,seg[::len(seg)//50],**style)
221+
if len(seg) > MAX_POINTS_IN_CURVE: # downsample due to OpenGL error?
222+
vis.add(name+"_%d" % i,seg[::len(seg)//MAX_POINTS_IN_CURVE],**style)
219223
else:
220224
vis.add(name+"_%d" % i,seg,**style)
221225

@@ -290,12 +294,6 @@ def plot_scene(scene : SceneState, ground_truth_vehicle=None, vehicle_model = No
290294
def plot(state : AllState, ground_truth_vehicle = None, vehicle_model=None, title=None, show=True):
291295
plot_scene(state, ground_truth_vehicle=ground_truth_vehicle, vehicle_model=vehicle_model, title=title, show=show)
292296
if state.route is not None:
293-
<<<<<<< HEAD
294-
plot_path("route",state.route,color=(1,0.5,0,1))
295-
if state.trajectory is not None:
296-
plot_path("trajectory",state.trajectory,color=(1,0,0,1),width=2)
297-
=======
298297
plot_path("route",state.route,color=(1,0.5,0,1),width=2)
299298
if state.trajectory is not None:
300299
plot_path("trajectory",state.trajectory,color=(1,0,0,1),width=3)
301-
>>>>>>> 32c90b400b9e1f01833a3bd9788abdab03565978

HOMEWORK.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Part 1:
5454

5555
Replicate your sensor printing and distress signal code in the BlinkDistress class in blink_component.py. You will need to adapt your code from using ROS subscribers / publishers to using the `GEMVehicleInterface` and `GEMVehicleReading` objects provided in the template code. Opening the GEMstack folder in the VSCode IDE will help you find the documentation for these classes.
5656

57-
Run your code in simulation first. (If you are running on the vehicle, first open one terminal window and run `roscore`. Keep this running.) Then, in the GEMstack folder, run `python3 main.py --variant=sim launch/blink_launch.yaml`. You should see your blinking sequence in a matplotlib window. Use Ctrl+C to quit.
57+
Run your code in simulation first. (If you are running on the vehicle, first open one terminal window and run `roscore`. Keep this running.) Then, in the GEMstack folder, run `python3 main.py --variant=sim launch/blink_launch.yaml`. You should see your blinking sequence in a 3D visualization window. Use Ctrl+C to quit.
5858

5959
Now, run your code on the real vehicle. Enable Pacmod control as before, then run `python3 main.py launch/blink_launch.yaml`.
6060

homework/blink_launch.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@ mission_execution: StandardExecutor
55
require_engaged: False
66
# Recovery behavior after a component failure
77
recovery:
8+
perception:
9+
state_estimation : GNSSStateEstimator
10+
perception_normalization : StandardPerceptionNormalizer
811
planning:
912
trajectory_tracking : blink_component.BlinkDistress
1013
# Driving behavior for the GEM vehicle. Runs perception and planner but doesn't execute anything (no controller).
1114
drive:
15+
perception:
16+
state_estimation : GNSSStateEstimator
17+
perception_normalization : StandardPerceptionNormalizer
1218
planning:
1319
trajectory_tracking : blink_component.BlinkDistress
1420
log:

0 commit comments

Comments
 (0)