Skip to content

Commit

Permalink
Merge branch 'master' into editor-robot-api
Browse files Browse the repository at this point in the history
Fix merge conflicts.
  • Loading branch information
Hal-9k1 committed Dec 5, 2024
2 parents fed6cfa + 732b0be commit 5376ecd
Show file tree
Hide file tree
Showing 12 changed files with 339 additions and 207 deletions.
19 changes: 19 additions & 0 deletions assets/pie.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 48 additions & 1 deletion src/common/DeviceInfoState.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,53 @@
/**
* Numeric device types which appear before the underscore in device ids.
*/
export enum DeviceType {
/**
* Dummy device type.
*/
DUMMY = 0,
/**
* Limit switch device type.
*/
LIMIT_SWITCH = 1,
/**
* Line follower device type.
*/
LINE_FOLLOWER = 2,
/**
* Battery buzzer device type. Not used anymore?
*/
BATTERY_BUZZER = 3,
/**
* Servo controller device type.
*/
SERVO_CONTROLLER = 4,
/**
* PolarBear device type. Not distributed with new kits.
*/
POLAR_BEAR = 5,
/**
* KoalaBear device type.
*/
KOALA_BEAR = 6,
/**
* Power distribution board device type.
*/
PDB = 7,
/**
* Distance sensor device type.
*/
DISTANCE_SENSOR = 8,
/**
* Stopwatch ("custom data" that tracks duration of connection in ms) device type.
*/
STOPWATCH = 32,
}

/**
* Maps device types to user-friendly names.
*/
export const DeviceTypes: { [type: number]: string } = {
export const DeviceTypeNames: { [type: number]: string } = {
0: 'Dummy device',
1: 'Limit switch',
2: 'Line follower',
Expand All @@ -11,6 +57,7 @@ export const DeviceTypes: { [type: number]: string } = {
6: 'KoalaBear motor controller',
7: 'Power distribution board',
8: 'Distance sensor',
32: 'Stopwatch',
};

/**
Expand Down
8 changes: 0 additions & 8 deletions src/common/IpcEventTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ export interface RendererInitData {
* The IP address used to communicate with the robot's runtime, retrieved from persistent config.
*/
robotIPAddress: string;
/**
* The IP address used to upload code to the robot, retrieved from persistent config.
*/
robotSSHAddress: string;
/**
* The IP address of the field controller, retrieved from persistent config.
*/
Expand Down Expand Up @@ -286,10 +282,6 @@ export interface MainQuitData {
* The IP address used to communicate with the robot's runtime, to be saved to persistent config.
*/
robotIPAddress: string;
/**
* The IP address used to upload code to the robot, to be saved to persistent config.
*/
robotSSHAddress: string;
/**
* The IP address of the field controller, to be saved to persistent config.
*/
Expand Down
104 changes: 66 additions & 38 deletions src/main/MainApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { BrowserWindow, FileFilter } from 'electron';
import fs from 'fs';
import { version as dawnVersion } from '../../package.json';
import AppConsoleMessage from '../common/AppConsoleMessage';
import DeviceInfoState from '../common/DeviceInfoState';
import DeviceInfoState, { DeviceType } from '../common/DeviceInfoState';
import type {
RendererChannels,
RendererInitData,
Expand Down Expand Up @@ -39,22 +39,22 @@ const CODE_FILE_FILTERS: FileFilter[] = [
* Relative path to persistent configuration file.
*/
const CONFIG_RELPATH = 'dawn-config.json';
/**
* Path on robot to upload student code to.
*/
const REMOTE_CODE_PATH = '/home/pi/runtime/executor/studentcode.py';
/**
* Port to use when connecting to robot with SSH.
*/
const ROBOT_SSH_PORT = 22;
/**
* Username to log in as when connecting to robot with SSH.
*/
const ROBOT_SSH_USER = 'pi';
const ROBOT_SSH_USER = 'ubuntu';
/**
* Password to log in with when connecting to robot with SSH.
*/
const ROBOT_SSH_PASS = 'raspberry';
const ROBOT_SSH_PASS = 'potato';
/**
* Path on robot to upload student code to.
*/
const REMOTE_CODE_PATH = `/home/${ROBOT_SSH_USER}/runtime/executor/studentcode.py`;

/**
* Adds a listener for the main-quit IPC event fired by the renderer.
Expand Down Expand Up @@ -140,6 +140,12 @@ export default class MainApp implements MenuHandler, RuntimeCommsListener {
*/
#preventQuit: boolean;

/**
* Whether error messages relating to connectivity will be suppressed. Used so disconnects only
* generate one log message and possibly (hopefully?) the causing error.
*/
#suppressNetworkErrors: boolean;

/**
* Persistent configuration loaded when MainApp is constructed and saved when the main window is
* closed.
Expand All @@ -165,6 +171,7 @@ export default class MainApp implements MenuHandler, RuntimeCommsListener {
this.#watcher = null;
this.#watchDebounce = true;
this.#preventQuit = true;
this.#suppressNetworkErrors = false;
this.#codeTransfer = new CodeTransfer(
REMOTE_CODE_PATH,
ROBOT_SSH_PORT,
Expand Down Expand Up @@ -196,7 +203,6 @@ export default class MainApp implements MenuHandler, RuntimeCommsListener {
addRendererListener('main-quit', (data) => {
// Save config that may have been changed while the program was running
this.#config.robotIPAddress = data.robotIPAddress;
this.#config.robotSSHAddress = data.robotSSHAddress;
this.#config.fieldIPAddress = data.fieldIPAddress;
this.#config.fieldStationNumber = data.fieldStationNumber;
this.#config.showDirtyUploadWarning = data.showDirtyUploadWarning;
Expand Down Expand Up @@ -246,7 +252,6 @@ export default class MainApp implements MenuHandler, RuntimeCommsListener {
this.#sendToRenderer('renderer-init', {
dawnVersion,
robotIPAddress: this.#config.robotIPAddress,
robotSSHAddress: this.#config.robotSSHAddress,
fieldIPAddress: this.#config.fieldIPAddress,
fieldStationNumber: this.#config.fieldStationNumber,
showDirtyUploadWarning: this.#config.showDirtyUploadWarning,
Expand All @@ -268,43 +273,66 @@ export default class MainApp implements MenuHandler, RuntimeCommsListener {

onReceiveDevices(deviceInfoState: DeviceInfoState[]) {
this.#sendToRenderer('renderer-devices-update', deviceInfoState);
}

onRuntimeTcpError(err: Error) {
this.#sendToRenderer(
'renderer-post-console',
new AppConsoleMessage(
'dawn-err',
`Encountered TCP error when communicating with Runtime. ${err.toString()}`,
),
const pdbs = deviceInfoState.filter(
(state) => state.id.split('_')[0] === DeviceType.PDB.toString(),
);
if (pdbs.length !== 1) {
this.#sendToRenderer(
'renderer-post-console',
new AppConsoleMessage(
'dawn-err',
'Cannot read battery voltage. Not exactly one PDB is connected to the robot.',
),
);
} else if (!('v_batt' in pdbs[0]) || Number.isNaN(Number(pdbs[0].v_batt))) {
this.#sendToRenderer(
'renderer-post-console',
new AppConsoleMessage(
'dawn-err',
'PDB does not have v_batt property or it is not a number.',
),
);
} else {
this.#sendToRenderer('renderer-battery-update', Number(pdbs[0].v_batt));
}
}

onRuntimeUdpError(err: Error) {
this.#sendToRenderer(
'renderer-post-console',
new AppConsoleMessage(
'dawn-err',
`Encountered UDP error when communicating with Runtime. ${err.toString()}`,
),
);
onRuntimeTcpError(err: Error) {
if (!this.#suppressNetworkErrors) {
this.#sendToRenderer(
'renderer-post-console',
new AppConsoleMessage(
'dawn-err',
`Encountered TCP error when communicating with Runtime. ${err.toString()}`,
),
);
}
}

onRuntimeError(err: Error) {
this.#sendToRenderer(
'renderer-post-console',
new AppConsoleMessage(
'dawn-err',
`Encountered error when communicating with Runtime. ${err.toString()}`,
),
);
if (!this.#suppressNetworkErrors) {
this.#sendToRenderer(
'renderer-post-console',
new AppConsoleMessage(
'dawn-err',
`Encountered error when communicating with Runtime. ${err.toString()}`,
),
);
}
}

onRuntimeDisconnect() {
this.#sendToRenderer(
'renderer-post-console',
new AppConsoleMessage('dawn-info', 'Disconnected from robot.'),
);
if (!this.#suppressNetworkErrors) {
this.#sendToRenderer(
'renderer-post-console',
new AppConsoleMessage('dawn-info', 'Disconnected from robot.'),
);
this.#suppressNetworkErrors = true;
}
}

onRuntimeConnect() {
this.#suppressNetworkErrors = false;
}

/**
Expand Down Expand Up @@ -393,7 +421,7 @@ export default class MainApp implements MenuHandler, RuntimeCommsListener {
}

/**
* Tries to load code from a file into the editor. Fails is the user does not choose a path.
* Tries to load code from a file into the editor. Fails if the user does not choose a path.
*/
#openCodeFile() {
const success = this.#showCodePathDialog('load');
Expand Down
2 changes: 1 addition & 1 deletion src/main/network/PacketStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export default class PacketStream extends Transform {
while (this.#tryReadPacket(shouldConcatHeader)) {
shouldConcatHeader = false;
}
callback(null, chunk);
callback();
}

/**
Expand Down
Loading

0 comments on commit 5376ecd

Please sign in to comment.