Skip to content

Commit

Permalink
Merge branch 'main' into 58-pod-improve-wheel-encoder-measurements
Browse files Browse the repository at this point in the history
  • Loading branch information
taesungh authored May 30, 2024
2 parents 079626c + d221109 commit 20f254a
Show file tree
Hide file tree
Showing 31 changed files with 927 additions and 275 deletions.
2 changes: 1 addition & 1 deletion control-station/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion control-station/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"prettier": "3.2.5",
"prettier": "^3.2.5",
"typescript": "^5.0.2",
"vite": "^4.4.5"
}
Expand Down
15 changes: 11 additions & 4 deletions control-station/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { ControlPanel, Navbar, SensorData } from "@/components";
import { ControlPanel, Navbar } from "@/components";
import usePodData from "./services/usePodData";
import PodContext from "./services/PodContext";
import { Dashboard } from "@/views";

function App() {
const { podData, podSocketClient } = usePodData();

return (
<main>
<Navbar />
<SensorData />
<ControlPanel />
<PodContext.Provider value={{ podData, podSocketClient }}>
<Navbar />
<Dashboard />
<ControlPanel />
</PodContext.Provider>
</main>
);
}
Expand Down
2 changes: 0 additions & 2 deletions control-station/src/components/ControlPanel/ControlPanel.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
.controlpanel {
position: fixed;
bottom: 0;
width: 100%;
background-color: black;
height: 9%;
Expand Down
8 changes: 6 additions & 2 deletions control-station/src/components/ControlPanel/ControlPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { useContext } from "react";

import PodContext from "@/services/PodContext";

import "./ControlPanel.css";
import usePodData from "@/services/usePodData";

function ControlPanel() {
const { podSocketClient } = usePodData();
const { podSocketClient } = useContext(PodContext);

return (
<div className="controlpanel">
<button className="button run" onClick={() => podSocketClient.sendRun()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ function SensorContainer() {
<SensorBox />
<SensorBox />
<SensorBox />
<SensorBox />
<SensorBox />
</div>
);
}
Expand Down
53 changes: 53 additions & 0 deletions control-station/src/components/StatusIndicator/StatusIndicator.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.status-indicator {
background-color: lightgray;
border-radius: 10px;
padding: 1rem;
margin: 2rem;
}

.group {
margin-bottom: 1rem;
}

.state-text {
display: inline-block;
vertical-align: middle;
}

.circle {
width: 25px;
height: 25px;
border-radius: 50%;
display: inline-block;
vertical-align: middle;
margin-right: 20px;
background-color: gray;
}

.disconnected-state > .active {
background-color: white;
}

.init-state > .active {
background-color: pink;
}

.running-state > .active {
background-color: green;
}

.stopped-state > .active {
background-color: red;
}

.halted-state > .active {
background-color: darkred;
}

.faulted-state > .active {
background-color: darkred;
}

.load-state > .active {
background-color: rgb(0, 100, 188);
}
26 changes: 26 additions & 0 deletions control-station/src/components/StatusIndicator/StatusIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useContext } from "react";

import PodContext from "@/services/PodContext";
import { State } from "@/services/PodSocketClient";

import "./StatusIndicator.css";

function StatusIndicator() {
const { podData } = useContext(PodContext);
const { state } = podData;

return (
<div className="status-indicator">
{Object.values(State).map((s) => {
return (
<div key={s} className={`group ${s.toLowerCase()}-state`}>
<span className={`circle` + (s === state ? " active" : "")}></span>
<div className="state-text">{s}</div>
</div>
);
})}
</div>
);
}

export default StatusIndicator;
1 change: 1 addition & 0 deletions control-station/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default as ControlPanel } from "./ControlPanel/ControlPanel";
export { default as Navbar } from "./Navbar/Navbar";
export { default as SensorData } from "./SensorBoxes/SensorData";
export { default as Status } from "./Status/Status";
export { default as StatusIndicator } from "./StatusIndicator/StatusIndicator";
16 changes: 16 additions & 0 deletions control-station/src/services/PodContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createContext } from "react";

import PodSocketClient, { PodData } from "./PodSocketClient";

interface PodContext {
podSocketClient: PodSocketClient;
podData: Readonly<PodData>;
}

// Initialize with unusable object assuming proper values are always provided
const PodContext = createContext<PodContext>({
podSocketClient: {} as PodSocketClient,
podData: {} as PodData,
});

export default PodContext;
21 changes: 19 additions & 2 deletions control-station/src/services/PodSocketClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ import { Dispatch, SetStateAction } from "react";
import { Socket } from "socket.io-client";
import { ioNamespace } from "./socketHandler";

export enum State {
Disconnected = "Disconnected",
Init = "Init",
Load = "Load",
Running = "Running",
Stopped = "Stopped",
Halted = "Halted",
Faulted = "Faulted",
}

interface ServerToClientEvents {
connect: () => void;
disconnect: (reason: Socket.DisconnectReason) => void;
Expand All @@ -17,6 +27,7 @@ interface ClientToServerEvents {

export interface PodData {
connected: boolean;
state: State;
}

type SetPodData = Dispatch<SetStateAction<PodData>>;
Expand Down Expand Up @@ -63,35 +74,41 @@ class PodSocketClient {
sendLoad(): void {
this.socket.emit("load", (response: string) => {
console.log("Server acknowledged:", response);
this.setPodData((d) => ({ ...d, state: State.Load }));
});
}

sendRun(): void {
this.socket.emit("run", (response: string) => {
console.log("Server acknowledged:", response);
this.setPodData((d) => ({ ...d, state: State.Running }));
});
}

sendStop(): void {
this.socket.emit("stop", (response: string) => {
console.log("Server acknowledged:", response);
this.setPodData((d) => ({ ...d, state: State.Stopped }));
});
}

sendHalt(): void {
this.socket.emit("halt", (response: string) => {
console.log("Server acknowledged:", response);
this.setPodData((d) => ({ ...d, state: State.Halted }));
});
}

private onConnect(): void {
console.log("Connected to server as", this.socket.id);
this.setPodData((d) => ({ ...d, connected: true }));
// TODO: On connecting, the state below should be what's provided by the pod
// if it's already running. Otherwise, the states should be State.Init
this.setPodData((d) => ({ ...d, connected: true, state: State.Init }));
}

private onDisconnect(reason: Socket.DisconnectReason): void {
console.log(`Disconnected from server: ${reason}`);
this.setPodData((d) => ({ ...d, connected: false }));
this.setPodData((d) => ({ ...d, connected: false, state: State.Disconnected }));
}

private onData(data: string): void {
Expand Down
3 changes: 2 additions & 1 deletion control-station/src/services/usePodData.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useEffect, useMemo, useState } from "react";
import PodSocketClient, { PodData } from "./PodSocketClient";
import PodSocketClient, { PodData, State } from "./PodSocketClient";

function usePodData() {
const [podData, setPodData] = useState<PodData>({
state: State.Disconnected,
connected: false,
});

Expand Down
14 changes: 3 additions & 11 deletions control-station/src/views/Dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
import { Status } from "@/components";
import usePodData from "@/services/usePodData";
import { SensorData, StatusIndicator } from "@/components";

function Dashboard() {
const { podData, podSocketClient } = usePodData();

return (
<div>
<h1>Dashboard</h1>
<Status />
<p>{podData.connected ? "connected" : "disconnected"}</p>
<button onClick={() => podSocketClient.sendStop()}>Send Stop</button>
<button onClick={() => podSocketClient.sendHalt()}>Send Halt</button>
<button onClick={() => podSocketClient.sendLoad()}>Send Load</button>
<button onClick={() => podSocketClient.sendRun()}>Send Run</button>
<SensorData />
<StatusIndicator />
</div>
);
}
Expand Down
Loading

0 comments on commit 20f254a

Please sign in to comment.