Skip to content

Commit

Permalink
add camera feed and control pad
Browse files Browse the repository at this point in the history
  • Loading branch information
roywei committed Jun 1, 2024
1 parent 47d7d1f commit 8752e7e
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 0 deletions.
19 changes: 19 additions & 0 deletions app/components/camera-feed.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.cameraFeed {
display: flex;
flex-direction: column;
align-items: center;
background-color: #f0f0f0;
border-radius: 8px;
padding: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.video {
width: 100%;
border-radius: 8px;
}

.image {
width: 100%;
border-radius: 8px;
}
17 changes: 17 additions & 0 deletions app/components/camera-feed.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use client";

import React, { useEffect, useState } from 'react';
import styles from './camera-feed.module.css';

const CameraFeed = () => {
const [imageSrc, setImageSrc] = useState('http:https://192.168.86.48:5000/video_feed');

return (
<div className={styles.cameraFeed}>
<h2>Camera Feed</h2>
<img src={imageSrc} alt="Camera Feed" className={styles.image} />
</div>
);
};

export default CameraFeed;
40 changes: 40 additions & 0 deletions app/components/control-pad.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.controlPad {
display: grid;
grid-template-rows: repeat(3, 1fr);
gap: 10px;
justify-items: center;
align-items: center;
}

.row {
display: flex;
gap: 10px;
justify-content: center;
}

.button, .stopButton {
background-color: #f0f0f0;
border: none;
padding: 15px 20px; /* Adjust padding for compactness */
text-align: center;
font-size: 14px; /* Adjust font size if needed */
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
cursor: pointer;
transition: background-color 0.3s ease;
width: 100px; /* Ensure all buttons are the same size */
height: 100px;
}

.button:hover {
background-color: #e0e0e0;
}

.stopButton {
background-color: #ff4d4d;
height: 100px;
}

.stopButton:hover {
background-color: #ff1a1a;
}
45 changes: 45 additions & 0 deletions app/components/control-pad.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"use client";

import React from 'react';
import styles from './control-pad.module.css';

const ControlPad = () => {
const sendCommand = async (command: string) => {
try {
const response = await fetch(`http:https://192.168.86.48:5000/${command}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
speed: 0.3,
time: 0.5
}),
});

if (!response.ok) {
throw new Error(`Failed to send command: ${command}`);
}
} catch (error) {
console.error('Error:', error);
}
};

return (
<div className={styles.controlPad}>
<div className={styles.row}>
<button className={styles.button} onClick={() => sendCommand('move_forward')}>Forward</button>
</div>
<div className={styles.row}>
<button className={styles.button} onClick={() => sendCommand('turn_left')}>Left</button>
<button className={styles.stopButton} onClick={() => sendCommand('stop')}>Stop</button>
<button className={styles.button} onClick={() => sendCommand('turn_right')}>Right</button>
</div>
<div className={styles.row}>
<button className={styles.button} onClick={() => sendCommand('move_backward')}>Backward</button>
</div>
</div>
);
};

export default ControlPad;
44 changes: 44 additions & 0 deletions app/examples/car-control/page.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.main {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}

.container {
display: flex;
width: 100%;
height: 100vh;
}

.column {
display: flex;
flex-direction: column;
width: 50%;
height: calc(100% - 40px);
gap: 20px;
margin: 20px;
justify-content: space-between;
}

.column > * {
border-radius: 16px;
overflow: hidden;
width: 100%;
height: 50%;
border-radius: 16px;
}
.chatContainer {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
background-color: white;
}

.chat {
max-width: 600px;
width: 100%;
height: 100%;
}
61 changes: 61 additions & 0 deletions app/examples/car-control/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client";

import React from 'react';
import Chat from "../../components/chat";
import CameraFeed from '../../components/camera-feed';
import ControlPad from '../../components/control-pad';
import styles from './page.module.css';
import { handleMoveForward, handleMoveBackward, handleTurnLeft, handleTurnRight, handleStop } from '../../utils/car-control';

const CarControlPage = () => {
const functionCallHandler = async (call) => {
const { function: { name }, arguments: args } = call;
let result;

try {
const parsedArgs = args ? JSON.parse(args) : {};
switch (name) {
case "move_forward":
result = await handleMoveForward(parsedArgs);
break;
case "move_backward":
result = await handleMoveBackward(parsedArgs);
break;
case "turn_left":
result = await handleTurnLeft(parsedArgs);
break;
case "turn_right":
result = await handleTurnRight(parsedArgs);
break;
case "stop":
result = await handleStop();
break;
default:
result = { error: "Unknown function" };
}
} catch (error) {
console.error('Error handling function call:', error);
result = { error: error.message };
}

return JSON.stringify(result);
};

return (
<main className={styles.main}>
<div className={styles.container}>
<div className={styles.column}>
<CameraFeed />
<ControlPad />
</div>
<div className={styles.chatContainer}>
<div className={styles.chat}>
<Chat functionCallHandler={functionCallHandler}/>
</div>
</div>
</div>
</main>
);
};

export default CarControlPage;
55 changes: 55 additions & 0 deletions app/utils/car-control.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
async function handleMoveForward(args) {
const response = await fetch("http:https://192.168.86.48:5000/move_forward", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(args),
});
return await response.json();
}

async function handleMoveBackward(args) {
const response = await fetch("http:https://192.168.86.48:5000/move_backward", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(args),
});
return await response.json();
}

async function handleTurnLeft(args) {
const response = await fetch("http:https://192.168.86.48:5000/turn_left", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(args),
});
return await response.json();
}

async function handleTurnRight(args) {
const response = await fetch("http:https://192.168.86.48:5000/turn_right", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(args),
});
return await response.json();
}

async function handleStop() {
const response = await fetch("http:https://192.168.86.48:5000/stop", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
return await response.json();
}

export { handleMoveForward, handleMoveBackward, handleTurnLeft, handleTurnRight, handleStop}

0 comments on commit 8752e7e

Please sign in to comment.