diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..c15eb26 Binary files /dev/null and b/.DS_Store differ diff --git a/.idea/aws.xml b/.idea/aws.xml index ec328d0..a851319 100644 --- a/.idea/aws.xml +++ b/.idea/aws.xml @@ -1,7 +1,6 @@ - \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2847457 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM ubuntu:22.04 + +RUN apt-get update && apt-get install -y \ + curl \ + bash \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +RUN curl -sfL https://github.com/eclipse-ankaios/ankaios/releases/download/v0.6.0/install.sh | INSTALL_ANK_SERVER_RUST_LOG=debug INSTALL_ANK_AGENT_RUST_LOG=info bash -s -- -t both + +ENV PATH="/root/.local/bin:$PATH" + +EXPOSE 25551 + +CMD ["ank-server"] \ No newline at end of file diff --git a/python/carla-connection.py b/python/carla-connection.py new file mode 100644 index 0000000..f940965 --- /dev/null +++ b/python/carla-connection.py @@ -0,0 +1,99 @@ +import json +import sys +import time +import math +import zenoh + +# Add CARLA egg to PYTHONPATH +# Replace with your actual path to carla-.egg if needed +try: + sys.path.append('path/to/carla-.egg') # Only if not installed via pip + import carla +except ImportError: + print("CARLA egg not found. Please update the sys.path line.") + sys.exit(1) + +def get_speed(velocity): + """Calculate speed in m/s from velocity vector""" + return math.sqrt(velocity.x**2 + velocity.y**2 + velocity.z**2) + +def main(): + #--------- CONFIG ---------- + POSE_TOPIC = 'vehicle/pose' #Vehicle Position info + IMU_TOPIC = 'vehicle/imu/raw' #Raw IMU + RATE_HZ = 20 + ZENOH_CONNECT = {} + # ------------------------- + try: + # Connect to CARLA server + client = carla.Client("localhost", 2000) + client.set_timeout(5.0) + + world = client.get_world() + + # Get all vehicles + vehicles = world.get_actors().filter('vehicle.*') + if not vehicles: + print("No vehicles found in the simulation.") + return + + # Pick the first vehicle + vehicle = vehicles[0] + print(f"Tracking vehicle: ID {vehicle.id}, Type {vehicle.type_id}\n") + + session = zenoh.open(ZENOH_CONNECT) + pub_pose = session.declare_publisher(POSE_TOPIC) + pub_imu = session.publish(IMU_TOPIC) + # Poll info every 0.5 seconds + while True: + + t0 = time.time() + + transform = vehicle.get_transform() + velocity = vehicle.get_velocity() + acc = vehicle.get_acceleration() + + location, rotation = transform.location, transform.rotation + speed = get_speed(velocity) + + pose_msg = { + "ts": t0, + "x": location.x, + "y": location.y, + "yaw": math.radians(rotation.yaw), # CARLA gives in degrees + "speed": speed, + } + + pub_pose.put(json.dumps(pose_msg).encode("utf-8")) + + '----------IMU----------' + imu_msg = { + "ts": t0, + "src": "carla", + "hz": RATE_HZ, + "acc": {"x": acc.x, "y": acc.y, "z": acc.z} + } + + pub_imu.put(json.dumps(imu_msg).encode("utf-8")) + + + # Validate this if + ## if (rotation.yaw < -2.0): + ## # sends data to topics + ## session.put(vehicle_pose_topic, location) + ## session.put(vehicle_imu_raw_topic, rotation) + + print(f"Location: (X={location.x:.2f}, Y={location.y:.2f}, Z={location.z:.2f})") + print(f"Rotation: (Pitch={rotation.pitch:.2f}, Yaw={rotation.yaw:.2f}, Roll={rotation.roll:.2f})") + print(f"Speed: {speed:.2f} m/s") + print("-" * 40) + + time.sleep(0.5) + + except KeyboardInterrupt: + print("\nExiting gracefully.") + except Exception as e: + print(f"Error: {e}") + +if __name__ == "__main__": + main() diff --git a/python/listener.py b/python/listener.py new file mode 100644 index 0000000..faa517c --- /dev/null +++ b/python/listener.py @@ -0,0 +1,87 @@ +import json +import sys +import time +import math +import zenoh + + +# tiny state +state = { + "last_imu_ts": 0.0, + "prev_acc_z": None, + "last_event_ts": 0.0, + "last_pose": {"speed_mps": 0.0, "x": 0.0, "y": 0.0} +} + + +#changable variables +MIN_SPEED = 4.0 # m/s (~14 km/h) +DELTA_Z_TH = 2.5 # m/s^2 change between consecutive samples +DEBOUNCE_S = 1.5 # seconds between events +#------------------- + +def severity_from_delta(dz): + if dz > 4.0: return "HIGH" + if dz > 3.0: return "MED" + return "LOW" + +def position_listener(sample): + try: + data = json.loads(sample.payload.decode("utf-8")) + state["last_pose"] = data + except Exception as e: + print(f"[listener] pose parse err: {e}") + +def imu_listener(sample): + try: + data = json.loads(sample.payload.decode("utf-8")) + ts = float(data.get("ts", time.time())) + acc = data.get("acc", {}) + acc_z = float(acc.get("z", 0.0)) + speed = float(state["last_pose"].get("speed_mps", 0.0)) + + prev = state["prev_acc_z"] + state["prev_acc_z"] = acc_z + + ## On the first IMU sample theres no previous acc_z to compare against + if prev is None: + return + + ## In theory potholes will cause a sharp change so a big dz (Delta-z acceleration, calculates the absolute change in vertical acceleration) + dz = abs(acc_z - prev) + now = ts + + ''' Little help from our 5th member ChatGPT on doing these calculations ''' + if speed >= MIN_SPEED and dz >= DELTA_Z_TH and (now - state["last_event_ts"]) >= DEBOUNCE_S: + sev = severity_from_delta(dz) + x = state["last_pose"].get("x", 0.0) + y = state["last_pose"].get("y", 0.0) + print(f"[POTHOLE] {sev} at ({x:.1f},{y:.1f}) | variation_acc_z={dz:.2f} m/s2 speed={speed:.1f} m/s") + state["last_event_ts"] = now + + except Exception as e: + print(f"[listener] imu parse err: {e}") + +def main(): + # Open Zenoh session + print("[Listener] Opening Zenoh session...") + session = zenoh.open({}) + + POSE_TOPIC = 'vehicle/pose' #Vehicle Position info + IMU_TOPIC = 'vehicle/imu/raw' #Raw IMU + print(f"[Subscriber] Subscribing to: {IMU_TOPIC} and {POSE_TOPIC}") + session.declare_subscriber(POSE_TOPIC, position_listener) + session.declare_subscriber(IMU_TOPIC, imu_listener) + + # Keep the subscriber running + try: + print("[Listener] Listening for data. Press Ctrl+C to stop") + while True: + time.sleep(1) + except KeyboardInterrupt: + print("\n[Listener] Shutting down") + finally: + session.close() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/python/potholes.py b/python/potholes.py index 9d011e5..ddfdeb0 100644 --- a/python/potholes.py +++ b/python/potholes.py @@ -3,7 +3,7 @@ import random import time -def spawn_pothole(world, bp_lib, location, scale=(2.0, 2.0, 0.2)): +def spawn_pothole(world, bp_lib, location, scale=(2.0, 2.0, 0.08)): """ Spawn a thin cube collider to simulate a pothole. """ @@ -13,7 +13,11 @@ def spawn_pothole(world, bp_lib, location, scale=(2.0, 2.0, 0.2)): transform = carla.Transform(location, carla.Rotation()) pothole = world.try_spawn_actor(cube_bp, transform) if pothole: - pothole.set_simulate_physics(True) + try: + pothole.set_simulate_physics(True) + pothole.set_enable_gravity(True) + except: + pass print(f"Spawned pothole at {location}") else: print("Failed to spawn pothole") @@ -58,7 +62,7 @@ def main(): # Put vehicle on autopilot vehicle.set_autopilot(True) - + print("Simulation running for 20 seconds..") # Let simulation run time.sleep(20) diff --git a/requirements.txt b/requirements.txt index e69de29..2f2be28 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,7 @@ +certifi==2025.4.26 +cffi==1.17.1 +cryptography==44.0.3 +pycparser==2.22 +wheel==0.45.1 +carla==0.9.16 +eclipse-zenoh==1.5.1