Skip to content

Commit

Permalink
Merge pull request #184 from COS301-SE-2024/feature/lane_objects_dete…
Browse files Browse the repository at this point in the history
…ction

Feature/lane objects detection
  • Loading branch information
d1scrd authored Sep 30, 2024
2 parents 2626c67 + fb18edf commit 1a6f195
Show file tree
Hide file tree
Showing 44 changed files with 11,553 additions and 12 deletions.
5 changes: 3 additions & 2 deletions Desktop/src/components/ProcessPopup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
export let models = [];
export let selectedModelName;
let localSelcted = "server";
let localSelcted = "local";
const dispatch = createEventDispatcher();
Expand All @@ -37,7 +37,7 @@
if (event.target.value === "local") {
local = true;
} else {
local = false;
local = true;
}
localProcess.set(local);
}
Expand Down Expand Up @@ -75,6 +75,7 @@
</select>
{#if hasCuda}
<select
style="visibility: hidden"
on:change={handleLocalChange}
bind:value={localSelcted}
class="mt-2 p-2 border rounded bg-highVizLight-secondary text-white"
Expand Down
10 changes: 10 additions & 0 deletions Desktop/src/components/SidebarV2.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@
// route: "#/visualize",
// iconPath: mdiEyeRefresh,
// },
{
name: "Start CARLA",
route: "#/startCarla",
iconPath: mdiCar,
},
{
name: "Visualizer",
route: "#/visualize",
iconPath: mdiEyeRefresh,
},
{
id: "go-to-drive-gallery",
name: "Drive Gallery",
Expand Down
57 changes: 52 additions & 5 deletions Desktop/src/electron.js
Original file line number Diff line number Diff line change
Expand Up @@ -1129,7 +1129,7 @@ ipcMain.handle('save-pipe-json', async (event, jsonString) => {
// Ensure the 'pipes' directory exists
const pipesDirectory = path.join(baseDirectory, 'pipes');
if (!fs.existsSync(pipesDirectory)) {
fs.mkdirSync(pipesDirectory, {recursive: true});
fs.mkdirSync(pipesDirectory, { recursive: true });
}

// File path for the pipes.json
Expand All @@ -1139,21 +1139,68 @@ ipcMain.handle('save-pipe-json', async (event, jsonString) => {
let existingData = [];
if (fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(filePath, 'utf-8');
existingData = JSON.parse(fileContent);

// Parse the content and ensure it is an array
try {
const parsedData = JSON.parse(fileContent);
if (Array.isArray(parsedData)) {
existingData = parsedData; // If it's an array, use it
} else {
console.warn('Existing data is not an array, initializing as empty array');
}
} catch (error) {
console.error('Error parsing JSON:', error);
}
}

// Append the new JSON data
existingData.push(JSON.parse(jsonString));
const newEntry = JSON.parse(jsonString);
existingData.push(newEntry); // Now safe because we ensured it's an array

// Write the updated data back to the file
fs.writeFileSync(filePath, JSON.stringify(existingData, null, 2), 'utf-8');

return {success: true, message: 'JSON data saved successfully!'};
return { success: true, message: 'JSON data saved successfully!' };
} catch (error) {
console.error('Error saving JSON data:', error);
return {success: false, message: 'Failed to save JSON data.'};
return { success: false, message: 'Failed to save JSON data.' };
}
});

ipcMain.handle('get-pipe-json', async (event) => {
try {
// Determine the base directory based on the operating system
let baseDirectory;
const platform = os.platform();
if (platform === 'win32') {
baseDirectory = path.join(process.env.APPDATA, 'HVstore');
} else if (platform === 'linux') {
baseDirectory = path.join(os.homedir(), '.local', 'share', 'HVstore');
} else {
baseDirectory = path.join(process.env.APPDATA, 'HVstore'); // Default to Windows for unsupported OS
}

// File path for the pipes.json
const pipesDirectory = path.join(baseDirectory, 'pipes');
const filePath = path.join(pipesDirectory, 'pipes.json');

// Check if the pipes.json file exists
if (!fs.existsSync(filePath)) {
return { success: true, data: [], message: 'No data found.' };
}

// Read and parse the JSON data
const fileContent = fs.readFileSync(filePath, 'utf-8');
const jsonData = JSON.parse(fileContent);

// Return the JSON data as an array
return { success: true, data: jsonData, message: 'Data retrieved successfully!' };
} catch (error) {
console.error('Error getting JSON data:', error);
return { success: false, message: 'Failed to retrieve JSON data.' };
}
});

ipcMain.handle('run-python-script2', async (event, scriptPath, args) => {
return new Promise((resolve, reject) => {
const pythonProcess = spawn('python', [scriptPath, ...args]);
Expand Down
1 change: 1 addition & 0 deletions Desktop/src/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
getFileSize: (filePath) => ipcRenderer.invoke('get-file-size', filePath),
savePipeJson: async (jsonString) => { const result = await ipcRenderer.invoke('save-pipe-json', jsonString); return result;},
runPythonScript2: (scriptPath, args = []) => ipcRenderer.invoke('run-python-script2', scriptPath, args),
getPipeJson: () => ipcRenderer.invoke('get-pipe-json'),
googleSignIn: () => ipcRenderer.invoke('google-sign-in'),
getAuthUrl: () => ipcRenderer.invoke('get-auth-url'),
exchangeCode: (code) => ipcRenderer.invoke('exchange-code', code),
Expand Down
240 changes: 240 additions & 0 deletions Desktop/src/routes/StartCarla.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
<script>
import ProtectedRoutes from "./ProtectedRoutes.svelte";
import Spinner from "../components/Spinner.svelte";
import { isLoading } from "../stores/loading";
import toast, { Toaster } from "svelte-french-toast";
import { Button } from "svelte-materialify";
import { onMount } from "svelte";
import { theme } from "../stores/themeStore"; // Importing the theme store
let pipes = [];
let selectedPipe = "";
let laneFollowing = false; // Boolean to track if the checkbox is checked
// Reactive statement to determine text color based on theme
$: textColor = $theme === "highVizLight" ? "black" : "white";
async function loadPipes() {
try {
const response = await window.electronAPI.getPipeJson();
if (response.success && response.data.length > 0) {
pipes = response.data;
selectedPipe = pipes[0].pipe;
} else {
pipes = ["Please create pipes"];
selectedPipe = pipes[0];
}
} catch (error) {
console.error("Error fetching pipes:", error);
pipes = [{ pipe: "Please create pipes" }];
selectedPipe = pipes[0];
}
}
onMount(() => {
loadPipes();
});
async function startCarla() {
isLoading.set(true);
if (laneFollowing) {
try {
const appPath = await window.electronAPI.getAppPath();
const appDirectory = await window.electronAPI.resolvePath(
appPath,
".."
);
const scriptPath = `${appDirectory}/Process/pipe4/temp/lane_following.py`;
// Pass the selected pipe as an argument to the Python script
const exitCode = await window.electronAPI.runPythonScript2(scriptPath, []);
isLoading.set(false);
if (exitCode === 0) {
toast.success("CARLA ran successfully!", {
duration: 5000,
position: "top-center",
});
} else {
toast.error("Please check CARLA server!", {
duration: 5000,
position: "top-center",
});
}
} catch (error) {
isLoading.set(false);
console.error("Error running CARLA:", error);
} finally {
isLoading.set(false);
}
} else {
try {
const appPath = await window.electronAPI.getAppPath();
const appDirectory = await window.electronAPI.resolvePath(
appPath,
".."
);
const scriptPath = `${appDirectory}/Process/pipe4/temp/unit3.py`;
// Pass the selected pipe as an argument to the Python script
const exitCode = await window.electronAPI.runPythonScript2(scriptPath, [
selectedPipe,
]);
isLoading.set(false);
if (exitCode === 0) {
toast.success("CARLA ran successfully!", {
duration: 5000,
position: "top-center",
});
} else {
toast.error("Please check CARLA server!", {
duration: 5000,
position: "top-center",
});
}
} catch (error) {
isLoading.set(false);
console.error("Error running CARLA:", error);
} finally {
isLoading.set(false);
}
}
}
</script>

<ProtectedRoutes>
{#if $isLoading}
<div class="flex justify-center">
<Spinner />
</div>
{:else}
<Toaster />
<div class="center-content">
<!-- Apply text color dynamically based on theme -->
<p class="text-message" style="color: {textColor};">
Please start the CARLA server before pressing the button.
</p>
<p class="text-message" style="color: {textColor};">
Note: Build your pipe in the "Pipes" section.
</p>
<p class="text-message" style="color: {textColor};">
Controls:
</p>
<p class="text-message" style="color: {textColor};">
W,A,S,D-To move the car
</p>
<p class="text-message" style="color: {textColor};">
R to toggle reverse
</p>
<p class="text-message" style="color: {textColor};">
O to toggle object detection
</p>
<p class="text-message" style="color: {textColor};">
Q to toggle lane following
</p>

<!-- Button with dynamic text color -->
<Button
rounded
class="bg-dark-primary styled-button"
style="color: {textColor};"
on:click={startCarla}
>
Start CARLA
</Button>

<p class="select-message" style="color: {textColor};">
Please select a pipe below:
</p>

<!-- Styled Dropdown with dynamic text color and conditional disabling -->
<select
bind:value={selectedPipe}
class="styled-dropdown"
style="color: {textColor};"
disabled={laneFollowing}
>
{#each pipes as pipe}
<option value={pipe.pipe} style="color: {textColor};"
>{pipe.pipe}</option
>
{/each}
</select>

<!-- Checkbox to toggle lane following mode -->
<div class="lane-following-toggle">
<input
type="checkbox"
bind:checked={laneFollowing}
id="lane-following"
/>
<label for="lane-following" style="color: {textColor};"
>Enable Lane Following</label
>
</div>
</div>
{/if}
</ProtectedRoutes>

<style>
.center-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.text-message {
font-size: 1.2em;
margin-bottom: 20px;
text-align: center;
}
.select-message {
font-size: 1.2em;
margin-top: 20px;
text-align: center;
}
.styled-dropdown {
margin-top: 5px;
padding: 10px;
font-size: 1.2em;
border: 2px solid #ccc;
border-radius: 5px;
background-color: #007bff; /* Blue background */
background-repeat: no-repeat;
background-position: right 15px top 50%;
background-size: 12px 12px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
outline: none;
color: inherit; /* Inherit text color based on dynamic style */
}
.styled-dropdown:focus {
border-color: #ccc;
}
/* Dynamic styling for the button */
.styled-button {
margin-top: 10px;
color: inherit; /* Inherit text color based on dynamic style */
}
.lane-following-toggle {
margin-top: 20px;
display: flex;
align-items: center;
}
.lane-following-toggle input {
margin-right: 10px;
}
</style>
2 changes: 2 additions & 0 deletions Desktop/src/routes/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Invite from './Invite.svelte'
import Install from './Install.svelte'
import TeamView from './TeamView.svelte'
import TeamNetwork from './TeamNetwork.svelte'
import StartCarla from './StartCarla.svelte'
import Svelvet from './Svelvet.svelte'
import Tests from './Tests.svelte'

Expand All @@ -43,6 +44,7 @@ const routes = {
'/teamView': TeamView,
'/teamNetwork': TeamNetwork,
'/svelvet': Svelvet,
'/startCarla': StartCarla,
'/tests': Tests
};

Expand Down
Loading

0 comments on commit 1a6f195

Please sign in to comment.