Skip to content

Commit

Permalink
the journey continues, telemetry V4
Browse files Browse the repository at this point in the history
  • Loading branch information
Willtura committed Apr 4, 2024
1 parent bd50ae5 commit f729b5b
Show file tree
Hide file tree
Showing 9 changed files with 260 additions and 50 deletions.
7 changes: 7 additions & 0 deletions resources/webcontent/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,36 @@ body {
font-family: Arial, sans-serif;
margin: 2em 5em;
}

h1 {
color: #333;
font-size: 28px;
}

#cameraContainer {
gap: 1em;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}

.camera {
width: 45%;
height: auto;
}

img{
display:block;
max-width:500px;
}

button {
margin: 1em 0;
padding: 0.6em 1.2em;
font-size: 16px;
cursor: pointer;
}

.websocket-text button, .websocket-image button {
margin-top: 10px;
padding: 10px 20px;
Expand All @@ -39,6 +45,7 @@ button {
.websocket-text button:hover, .websocket-image button:hover {
background-color: #555;
}

.text_field {
max-height: 400px;
overflow-y: scroll;
Expand Down
12 changes: 6 additions & 6 deletions resources/webcontent/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
</head>
<body>
<h1>Dashboard</h1>
<div id="cameraContainer">
<websocket-image id="left"></websocket-image>
<websocket-image id="center"></websocket-image>
<websocket-image id="right"></websocket-image>
</div>
<websocket-text id="logs" append="true"></websocket-text>
<div id="cameraContainer">
<websocket-image id="left"></websocket-image>
<websocket-image id="center"></websocket-image>
<websocket-image id="right"></websocket-image>
</div>
<websocket-text id="logs" append="true"></websocket-text>
<script src="js/websocket_text_component.js"></script>
<script src="js/websocket_image_component.js"></script>
</body>
Expand Down
27 changes: 17 additions & 10 deletions resources/webcontent/js/websocket_image_component.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,56 @@
/**
* WebsocketImageComponent is a custom HTML element that displays an image received from a websocket server.
* It also includes a button to toggle the websocket connection.
*/
class WebsocketImageComponent extends HTMLElement {

constructor() {
super();

this.render();
this.connectWS();
}

/**
* Render the component by creating an image tag and a button.
* The button is used to toggle the websocket connection.
*/
render() {
// create an image tag
const header = document.createElement('h4')
header.textContent = this.getAttribute('id');


this.img = document.createElement('img');
this.img.style.width = '100%';
this.img.style.height = 'auto';

const button = document.createElement('button');
button.textContent = 'Toggle';
button.onclick = () => this.toggleWS();

// append the image and button to the dom
this.appendChild(header);
this.appendChild(button);
this.appendChild(this.img);
}

/**
* Send a 'toggle' message to the server to toggle the websocket connection.
*/
toggleWS() {
// send a toggle message to the server
console.log('toggle')
this.ws.send('toggle');
}

/**
* Establish a new websocket connection.
* When a new message is received, update the image.
* The image is sent as a base64 encoded JPEG.
*/
connectWS() {
// create a new websocket connection
this.ws = new WebSocket(`ws://localhost:8000/ws/${this.getAttribute('id')}`);
this.ws.onerror = (event) => {
console.error('Websocket error:', event);
}
this.ws.binaryType = 'arraybuffer';

// when a new message is received, update the image. the image is send as base64 encoded jpeg
this.ws.onmessage = (event) => {
console.log('data')
const img_src = "data:image/jpeg;base64," + event.data;
// check if it is the same as the current image
if (this.img.src === img_src) {
Expand All @@ -52,6 +60,5 @@ class WebsocketImageComponent extends HTMLElement {
}
}
}

// define the custom element
customElements.define('websocket-image', WebsocketImageComponent);
23 changes: 16 additions & 7 deletions resources/webcontent/js/websocket_text_component.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
/**
* WebsocketTextComponent is a custom HTML element that displays text received from a websocket server.
* It also includes a button to toggle the websocket connection.
*/
class WebsocketTextComponent extends HTMLElement {

constructor() {
super();

this.render();
this.connectWS();
}

/**
* Render the component by creating a text div and a button.
* The button is used to toggle the websocket connection.
*/
render() {
// create an image tag
const header = document.createElement('h4')
header.textContent = this.getAttribute('id');

this.text = document.createElement('div');
this.text.classList.add('text_field');

const button = document.createElement('button');
button.textContent = 'Toggle';
button.onclick = () => this.toggleWS();
Expand All @@ -23,13 +30,16 @@ class WebsocketTextComponent extends HTMLElement {
this.appendChild(button);
this.appendChild(this.text);
}

/**
* Send a 'toggle' message to the server to toggle the websocket connection.
*/
toggleWS() {
// send a toggle message to the server
console.log('toggle')
this.ws.send('toggle');
}

/**
* Establish a new websocket connection.
* When a new message is received, update the text.
*/
connectWS() {
// create a new websocket connection
this.ws = new WebSocket(`ws://localhost:8000/ws/${this.getAttribute('id')}`);
Expand All @@ -52,6 +62,5 @@ class WebsocketTextComponent extends HTMLElement {
}
}
}

// define the custom element
customElements.define('websocket-text', WebsocketTextComponent);
67 changes: 65 additions & 2 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,76 @@
import logging

from config import config
from constants import Gear
from driving.can_controller import CANController
from driving.can_controller.can_bus import get_can_interface
from driving.speed_controller import SpeedController, SpeedControllerState
from lane_assist.helpers import td_stitched_image_generator
from lane_assist.lane_assist import LaneAssist
from lane_assist.line_following.path_follower import PathFollower
from object_recognition.handlers.pedestrian_handler import PedestrianHandler
from object_recognition.handlers.speed_limit_handler import SpeedLimitHandler
from object_recognition.handlers.traffic_light_handler import TrafficLightHandler
from object_recognition.object_controller import ObjectController
from object_recognition.object_detector import ObjectDetector
from utils.video_stream import VideoStream
from telemetry.webapp.telemetry_server import TelemetryServer


def main() -> None:
"""Start the main loop."""
cam_left = VideoStream(config.camera_ids.left)
cam_center = VideoStream(config.camera_ids.center)
cam_right = VideoStream(config.camera_ids.right)

cam_left.start()
cam_center.start()
cam_right.start()

# Connect to CAN bus
bus = get_can_interface()
can_controller = CANController(bus)
speed_controller = SpeedController(can_controller)

# Initialize the speed controller
speed_controller.gear = Gear.DRIVE
speed_controller.state = SpeedControllerState.WAITING_TO_STOP
speed_controller.max_speed = 50

# Initialize the path follower
path_follower = PathFollower(1, 0.01, 0.05, look_ahead_distance=10)
path_follower.max_steering_range = 30.0

# # Initialize the object controller
controller = ObjectController(speed_controller)
controller.add_handler(PedestrianHandler(controller))
controller.add_handler(SpeedLimitHandler(controller))
controller.add_handler(TrafficLightHandler(controller))

# Initialize the lane assist
lane_assist = LaneAssist(
td_stitched_image_generator(cam_left, cam_center, cam_right),
path_follower,
speed_controller,
adjust_speed=lambda _: 1,
)

# Initialize the object detector
detector = ObjectDetector.from_model(config.object_detection.model_path, controller, 0)

# Start the system
can_controller.start()
speed_controller.start()
detector.start()
lane_assist.start()

server = TelemetryServer()
server.start()
input("Press Enter to exit...")
input("Press Enter to stop...")


if __name__ == "__main__":
"""The main function."""
main()
from simulator import main as smain

smain()
21 changes: 19 additions & 2 deletions src/telemetry/webapp/data_stream/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,29 @@


def create_router(websocket_handler: WebsocketHandler) -> APIRouter:
"""Create a FastAPI router for the data stream."""
"""
Create a FastAPI router for the data stream.
Args:
websocket_handler (WebsocketHandler): The handler for the websocket connections.
Returns:
APIRouter: The FastAPI router with the websocket endpoint.
"""
router = APIRouter()

@router.websocket("/ws/{name}")
async def websocket_endpoint(name: str, websocket: WebSocket) -> None:
"""Create a websocket endpoint."""
"""
Create a websocket endpoint.
Args:
name (str): The name of the websocket.
websocket (WebSocket): The websocket instance.
Returns:
None
"""
await websocket.accept()
client = websocket_handler.add_socket(name, websocket)
await client.rec_messages()
Expand Down
Loading

0 comments on commit f729b5b

Please sign in to comment.