Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 3.0.x #143

Open
wants to merge 59 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
a2d36a7
Push starter files
HaileyJang Mar 11, 2021
07f8b4f
updated keyboard connect/disconnect
uthmanmomen13 Mar 11, 2021
78eebf2
Videofeed Window In process
HaileyJang Mar 13, 2021
cfced80
removed unnecessary bitmap change in editor.tsx
uthmanmomen13 Mar 13, 2021
af275cd
Change buttons back to 0
ewc340 Mar 13, 2021
7a84455
Now the button is funky
HaileyJang Mar 13, 2021
85239a6
Merge branch 'keyboard-video-feed' of https://github.com/pioneers/daw…
HaileyJang Mar 13, 2021
bea3af7
Fix merge conflicts
ewc340 Mar 20, 2021
6cc06a8
Remove duplicate sendKeyboardInputs function
ewc340 Mar 20, 2021
345ce20
Change VideoFeed component to functional
ewc340 Mar 20, 2021
c545e02
Changed to functional component
HaileyJang Mar 20, 2021
e2bce0e
Fix merge conflict
HaileyJang Mar 20, 2021
a1b5d8c
Added Ovenplayer as module and added type declaration
HaileyJang Mar 23, 2021
5a1e627
Small naming change for main video player
ewc340 Mar 23, 2021
cae7025
Change video feed html title
ewc340 Mar 23, 2021
5e7328a
More changes
HaileyJang Mar 23, 2021
8add5a3
Fix network error
ewc340 Mar 23, 2021
b93beac
Add try/catch to RendererBridge reduxDispatch
ewc340 Mar 23, 2021
2b1b33a
Add maximize to video feed window
ewc340 Mar 23, 2021
e552479
Add overhead video feed and styling
ewc340 Mar 23, 2021
8bdc0bf
Fix variable spacing
ewc340 Mar 23, 2021
7269bdd
Fix merge conflict
HaileyJang Mar 24, 2021
2e4aeb5
Fixed button issue
HaileyJang Mar 27, 2021
d6b79b6
Add Shepherd overlay
ewc340 Mar 27, 2021
d804515
Add ctrl + q special case and make button text more explicit
ewc340 Mar 27, 2021
917a5ff
Fix merge conflicts
ewc340 Mar 27, 2021
2f7d39d
Add overlay url box
ewc340 Mar 28, 2021
b15de5b
Style tweaks
ewc340 Mar 28, 2021
a034d64
Fix sandstorm showing
ewc340 Mar 28, 2021
fe7dd19
Fix video feed button click, turn off scoreboard overlay toggling, an…
ewc340 Mar 30, 2021
cd2cbb0
Fix video feed multiple key send bug and Editor.tsx ctrl+q disconnect…
ewc340 Mar 31, 2021
de2f4a7
Merge branch 'dev' into shepherd-overlay
ewc340 Apr 10, 2021
0e5a296
Merge branch 'dev' into shepherd-overlay
ewc340 Apr 15, 2021
5717ede
Add new RendererBridge changes
ewc340 Apr 22, 2021
08f0c74
Integrate new RendererBridge changes in main-process and FieldControl
ewc340 Apr 22, 2021
adf28e8
Merge branch 'dev' into shepherd-overlay
ewc340 Apr 22, 2021
825bc67
Make scoreboard responsive
ewc340 Apr 22, 2021
86b87d8
Slight css tweak
ewc340 Apr 22, 2021
6689895
Add clearInterval for setInterval calls in Runtime
ewc340 Apr 29, 2021
aa21258
Fix merge conflicts from dev
ewc340 Apr 29, 2021
0629dd3
Switch Runtime connection establishment to TCP
ewc340 Apr 30, 2021
bbb1fe2
Make runtimeHeartbeat deprecated
ewc340 Apr 30, 2021
793bda9
Lint ConfigBox
ewc340 Apr 30, 2021
9eb2198
Change video feed naming
ewc340 Apr 30, 2021
bdcdb9e
Merge branch 'dev' into shepherd-overlay
ewc340 Apr 30, 2021
9499715
Remove runtimeHeartbeat from sagas
ewc340 Apr 30, 2021
f4b08db
Add connectionStatus: true in RUNTIME_CONNECT action
ewc340 Apr 30, 2021
ce002db
Remove formatter for js in webpack config
ewc340 Apr 30, 2021
5cf3d5b
Remove scoreboard toggle on/off for now - so always on for now
ewc340 Apr 30, 2021
7250195
Fix scoreboard outer container width and add newlines
ewc340 Apr 30, 2021
cf78092
Add another newline in scoreboard.html
ewc340 Apr 30, 2021
52d01d2
Add another newline in scoreboard.css
ewc340 Apr 30, 2021
2f8479e
Merge dev
ewc340 Oct 14, 2021
08ed3fe
Fix build errors
ewc340 Oct 14, 2021
d1b4f98
Bump version number to 3.0.1
ewc340 Oct 14, 2021
82e7c1d
Add try catch around entire switch case in socket on data block
ewc340 Oct 16, 2021
9f5efa4
Add more height between params in GenericPeripheral
ewc340 Oct 16, 2021
0ac9243
Fix fake runtime
ewc340 Oct 21, 2021
bc7753c
Push some fixes
ewc340 Oct 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 26 additions & 27 deletions fake-runtime/FakeRuntime.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/*
* Fake Runtime is not handled by webpack like most of the other JS code but instead
* will be run "as is" as a child-process of the rest of the application.
* See DebugMenu.js for handling FakeRuntime within Dawn
* Fake Runtime is run as a child-process of the rest of the application.
* See DebugMenu.js for handling FakeRuntime within Dawn.
*/

/* eslint-disable camelcase */
import { DevData, IParam, IDevice, IDevData } from '../protos-main';
import { createSocket, Socket as UDPSocket } from 'dgram';
import { createServer, Server as TCPServer } from 'net';
import { createServer, Server as TCPServer, Socket as TCPSocket } from 'net';

const TCP_PORT = 8101;
const UDP_SEND_PORT = 9001;
const UDP_LISTEN_PORT = 9000;
const MSG_INTERVAL_MSEC = 50;

const randomFloat = (min: number, max: number) => (max - min) * Math.random() + min;
const sensor = (name: string, type: number, params: IParam[], uid: number): IDevice => ({
name,
type,
params,
uid,
uid
});

const param = (name: string, type: string, value: any): IParam => ({
Expand All @@ -35,27 +32,18 @@ const print = (output: string) => {
};

class FakeRuntime {
sendSocket: UDPSocket;
listenSocket: UDPSocket;
tcpServer: TCPServer;

constructor() {
this.sendSocket = createSocket({ type: 'udp4', reuseAddr: true });
this.listenSocket = createSocket({ type: 'udp4', reuseAddr: true });

this.listenSocket.on('message', (_msg: any) => {
// TODO: Handle UDP gamepad recv
});
this.listenSocket.bind(UDP_LISTEN_PORT);

this.tcpServer = createServer((_c: any) => {
print('client connected');
});
this.tcpServer.listen(TCP_PORT, () => {
print('server bound');
})

setInterval(this.onInterval, MSG_INTERVAL_MSEC);
});
this.tcpServer.on('connection', (socket: TCPSocket) => {
setInterval(() => this.sendDeviceData(socket), MSG_INTERVAL_MSEC);
});
}

generateFakeData = () => {
Expand All @@ -71,7 +59,7 @@ class FakeRuntime {
[
param('Val 1', 'float', randomFloat(-100, 100)),
param('Val 2', 'float', randomFloat(-100, 100)),
param('Val 3', 'float', randomFloat(-100, 100)),
param('Val 3', 'float', randomFloat(-100, 100))
],
104
),
Expand All @@ -80,15 +68,26 @@ class FakeRuntime {
// Special Cases handled in dawn/renderer/reducers/peripherals.js
// sensor('Ignored', 5, [param('major', 'int', 1), param('minor', 'int', 2), param('patch', 'int', 3)], -1),
// sensor('Ignored', 5, [param('is_unsafe', 'bool', Math.random() < 0.5), param('v_batt', 'float', randomFloat(0, 15))], 0),
],
]
};
}
};

onInterval = () => {
sendDeviceData = (socket: TCPSocket) => {
const fakeData: IDevData = this.generateFakeData();
this.sendSocket.send(DevData.encode(fakeData).finish(), UDP_SEND_PORT, 'localhost');
const encodedPayload = DevData.encode(fakeData).finish();

const msgLength = Buffer.byteLength(encodedPayload);
const msgLengthArr = new Uint8Array([msgLength & 0x00ff, msgLength & 0xff00]); // Assuming little-endian byte order, since runs on x64
const msgTypeArr = new Uint8Array([3]); // msg type 3 for DevData
const packet = Buffer.concat([msgTypeArr, msgLengthArr, encodedPayload], msgLength + 3);

socket.write(packet, (err?: Error) => {
if (err !== undefined) {
console.log('Err', err);
}
});
// TODO: Handle TCP writes to console
}
};
}

new FakeRuntime();
7 changes: 7 additions & 0 deletions main/MenuTemplate/DebugMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ const DebugMenu: MenuItemConstructorOptions = {
});
},
},

{
label: 'Toggle Videofeed DevTools',
click() {
RendererBridge.toggleWindowDevtools('video_feed');
},
},
],
};

Expand Down
27 changes: 27 additions & 0 deletions main/main-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export default function showAPI() {
}

app.on('ready', () => {
let videoWindow: BrowserWindow | null = null;

Runtime.setup();
ipcMain.on('FC_CONFIG_CHANGE', FCObject.changeFCInfo);
ipcMain.on('FC_INITIALIZE', initializeFC);
Expand All @@ -73,6 +75,31 @@ app.on('ready', () => {
}
});

ipcMain.on('SHOW_VIDEO_FEED', () => {
if (!videoWindow) {
videoWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
},
width: 1000,
height: 700,
});
RendererBridge.registerWindow('video_feed', videoWindow);
videoWindow.on('closed', () => {
videoWindow = null;
});
videoWindow.maximize();
videoWindow.loadURL(`file://${__dirname}/../static/video-feed/video.html`);
videoWindow.webContents.on('dom-ready', () => RendererBridge.dispatch('video_feed', 'shepherdScoreboardServerIpAddress', FCObject.bridgeAddress))
videoWindow.on('ready-to-show', () => {
if (videoWindow) {
videoWindow.show();
}
});
}
})

// Binding for the main process to inject into Redux workflow
RendererBridge.registerWindow('main', mainWindow);

Expand Down
3 changes: 2 additions & 1 deletion main/networking/FieldControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class FCInternals {
}

init() {
this.socket = io(`http://${this.bridgeAddress}:7000`);
this.socket = io.connect(this.bridgeAddress);
this.socket.on('connect', () => {
this.logger.log('Connected to Field Control Socket');
this.socket!.on('robot_state', (data: any) => {
Expand Down Expand Up @@ -76,6 +76,7 @@ export const FCObject = {

if (arg.bridgeAddress !== null) {
FCObject.bridgeAddress = arg.bridgeAddress;
RendererBridge.dispatch('video_feed', 'shepherdScoreboardServerIpAddress', arg.bridgeAddress);
}
},
};
46 changes: 24 additions & 22 deletions main/networking/Runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as protos from '../../protos-main';
import RendererBridge from '../RendererBridge';
import { updateConsole } from '../../renderer/actions/ConsoleActions';
import { infoPerMessage } from '../../renderer/actions/InfoActions';
import { runtimeConnect, runtimeDisconnect } from '../../renderer/actions/InfoActions';
import { updatePeripherals } from '../../renderer/actions/PeripheralActions';
import { Logger, defaults } from '../../renderer/utils/utils';
import { Peripheral } from '../../renderer/types';
Expand Down Expand Up @@ -140,13 +141,14 @@ class RuntimeConnection {
logger: Logger;
socket: TCPSocket;
leftoverBytes: Buffer | undefined;
connectionInterval: ReturnType<typeof setInterval>;

constructor(logger: Logger) {
this.logger = logger;
this.socket = new TCPSocket();

// Connect to most recent IP
setInterval(() => {
this.connectionInterval = setInterval(() => {
if (!this.socket.connecting && this.socket.pending) {
if (runtimeIP !== defaults.IPADDRESS) {
let port = DEFAULT_TCP_PORT;
Expand All @@ -164,11 +166,12 @@ class RuntimeConnection {

this.socket.on('connect', () => {
this.logger.log('Runtime connected');
RendererBridge.reduxDispatch(runtimeConnect());
this.socket.write(new Uint8Array([1])); // Runtime needs first byte to be 1 to recognize client as Dawn (instead of Shepherd)
});

this.socket.on('end', () => {
// RendererBridge.reduxDispatch(runtimeDisconnect());
RendererBridge.reduxDispatch(runtimeDisconnect());
this.logger.log('Runtime disconnected');
});

Expand All @@ -187,22 +190,22 @@ class RuntimeConnection {
for (const packet of processedTCPPackets) {
let decoded;

switch (packet.type) {
case MsgType.LOG:
decoded = protos.Text.decode(packet.payload);
RendererBridge.reduxDispatch(updateConsole(decoded.payload));
break;
try {
switch (packet.type) {
case MsgType.LOG:
decoded = protos.Text.decode(packet.payload);
RendererBridge.reduxDispatch(updateConsole(decoded.payload));
break;

case MsgType.TIME_STAMPS:
decoded = protos.TimeStamps.decode(packet.payload);
const oneWayLatency = (Date.now() - Number(decoded.dawnTimestamp)) / 2;
case MsgType.TIME_STAMPS:
decoded = protos.TimeStamps.decode(packet.payload);
const oneWayLatency = (Date.now() - Number(decoded.dawnTimestamp)) / 2;

// TODO: we can probably do an average of n timestamps so the display doesn't change too frequently
RendererBridge.reduxDispatch(setLatencyValue(oneWayLatency));
break;
// TODO: we can probably do an average of n timestamps so the display doesn't change too frequently
RendererBridge.reduxDispatch(setLatencyValue(oneWayLatency));
break;

case MsgType.DEVICE_DATA:
try {
case MsgType.DEVICE_DATA:
RendererBridge.reduxDispatch(infoPerMessage());
const sensorData: protos.Device[] = protos.DevData.decode(packet.payload).devices;
const peripherals: Peripheral[] = [];
Expand All @@ -221,16 +224,15 @@ class RuntimeConnection {
peripherals.push({ ...device, uid: device.uid.toString() });
});
RendererBridge.reduxDispatch(updatePeripherals(peripherals));
} catch (err) {
this.logger.log(err);
}
break;
break;

default:
this.logger.log(`Unsupported received message type: ${packet.type}`)
default:
this.logger.log(`Unsupported received message type: ${packet.type}`);
}
} catch (err) {
this.logger.log(err);
}
}

this.leftoverBytes = leftoverBytes;
});

Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,17 @@
"bufferutil": "4.0.1",
"create-react-class": "15.6.2",
"electron-json-storage": "4.0.2",
"formik": "^2.2.6",
"html-loader": "^0.5.5",
"html-react-parser": "^1.2.4",
"immutable": "3.8.2",
"jquery": "^3.6.0",
"json-loader": "0.5.7",
"keymirror": "0.1.1",
"lodash": ">=4.17.21",
"mousetrap": "1.6.1",
"numeral": "2.0.6",
"object-assign": "4.1.1",
"ovenplayer": "^0.10.0-alpha.1",
"patch-package": "^6.2.2",
"postinstall-postinstall": "^2.1.0",
"prop-types": "15.6.0",
Expand All @@ -141,7 +144,7 @@
"redux-saga": "^1.1.3",
"seedrandom": "2.4.3",
"smalltalk": "^4.0.6",
"socket.io-client": "^2.3.0",
"socket.io-client": "^4.0.0",
"ssh2": "^0.8.9",
"superagent": "3.8.2",
"ts-node": "^9.0.0",
Expand Down
22 changes: 22 additions & 0 deletions renderer/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { remote, ipcRenderer } from 'electron';
import * as electronJSONStorage from 'electron-json-storage';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import smalltalk from 'smalltalk';
import { Dashboard } from './Dashboard';
import { DNav } from './DNav';
import { joyrideSteps } from './JoyrideSteps';
Expand All @@ -20,6 +21,12 @@ library.add(fas);

const storage = remote.require('electron-json-storage') as ElectronJSONStorage;

interface AlertType {
heading: string;
message: string;
id: number;
}

interface StateProps {
connectionStatus: boolean;
runtimeStatus: boolean;
Expand All @@ -41,6 +48,21 @@ export const AppComponent = (props: Props) => {
const [tourRunning, changeTourRunning] = useState(false);
startLog();

useEffect(() => {
const latestAlert = props.asyncAlerts[props.asyncAlerts.length - 1] as AlertType | undefined;

if (latestAlert !== undefined) {
smalltalk.alert(latestAlert.heading, latestAlert.message).then(
() => {
props.onAlertDone(latestAlert.id);
},
() => {
props.onAlertDone(latestAlert.id);
}
);
}
}, [props.asyncAlerts])

useEffect(() => {
addSteps(joyrideSteps);
ipcRenderer.on('start-interactive-tour', () => {
Expand Down
Loading