Skip to content

Commit

Permalink
Ev3 defensive tabs (#313)
Browse files Browse the repository at this point in the history
* Remove unused variable in Program

* Make the ev3 tabs more defensive
  • Loading branch information
JoelChanZhiYang authored May 5, 2024
1 parent 5ae9a23 commit f7a4cfa
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class Program implements Controller {

// steps per tick
for (let i = 0; i < this.config.stepsPerTick; i++) {
const result = this.iterator.next();
this.iterator.next();
}
} catch (e) {
console.error(e);
Expand Down
17 changes: 10 additions & 7 deletions src/bundles/robot_simulation/engine/World.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ export class World extends TypedEventTarget<WorldEventMap> {
robotConsole: RobotConsole;
controllers: ControllerGroup;

constructor(physics: Physics, render: Renderer, timer: Timer, robotConsole: RobotConsole) {
constructor(
physics: Physics,
render: Renderer,
timer: Timer,
robotConsole: RobotConsole
) {
super();
this.state = 'unintialized';
this.physics = physics;
Expand Down Expand Up @@ -71,10 +76,7 @@ export class World extends TypedEventTarget<WorldEventMap> {

private setState(newState: WorldState) {
if (this.state !== newState) {
this.dispatchEvent(
'worldStateChange',
new Event('worldStateChange'),
);
this.dispatchEvent('worldStateChange', new Event('worldStateChange'));
this.state = newState;
}
}
Expand All @@ -90,6 +92,7 @@ export class World extends TypedEventTarget<WorldEventMap> {
window.requestAnimationFrame(this.step.bind(this));
}
}

step(timestamp: number) {
try {
const frameTimingInfo = this.timer.step(timestamp);
Expand All @@ -99,12 +102,12 @@ export class World extends TypedEventTarget<WorldEventMap> {
// Update render
this.dispatchEvent(
'beforeRender',
new TimeStampedEvent('beforeRender', physicsTimingInfo),
new TimeStampedEvent('beforeRender', physicsTimingInfo)
);
this.render.step(frameTimingInfo);
this.dispatchEvent(
'afterRender',
new TimeStampedEvent('afterRender', physicsTimingInfo),
new TimeStampedEvent('afterRender', physicsTimingInfo)
);

if (this.state === 'running') {
Expand Down
18 changes: 13 additions & 5 deletions src/tabs/RobotSimulation/components/Simulation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,16 @@ export const SimulationCanvas: React.FC<SimulationCanvasProps> = ({
}) => {
const ref = useRef<HTMLDivElement>(null);
const sensorRef = useRef<HTMLDivElement>(null);
const [currentState, setCurrentState]
= useState<WorldState>('unintialized');
const [currentState, setCurrentState] = useState<WorldState>('unintialized');

// We know this is true because it is checked in RobotSimulation/index.tsx (toSpawn)
const world = context.context.moduleContexts.robot_simulation.state
.world as World;

const ev3 = context.context.moduleContexts.robot_simulation.state
.ev3 as DefaultEv3;
// This is not guaranteed to be true.
const ev3 = context.context.moduleContexts.robot_simulation.state.ev3 as
| DefaultEv3
| undefined;

const robotConsole = world.robotConsole;

Expand All @@ -65,9 +68,14 @@ export const SimulationCanvas: React.FC<SimulationCanvasProps> = ({
if (ref.current) {
ref.current.replaceChildren(world.render.getElement());
}
if (!ev3) {
return;
}

if (sensorRef.current) {
sensorRef.current.replaceChildren(ev3.get('colorSensor').renderer.getElement());
sensorRef.current.replaceChildren(
ev3.get('colorSensor').renderer.getElement()
);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,29 @@ import { useFetchFromSimulation } from '../../hooks/fetchFromSimulation';
import { LastUpdated } from './tabComponents/LastUpdated';
import { TabWrapper } from './tabComponents/Wrapper';

export const ColorSensorPanel: React.FC<{ ev3: DefaultEv3 }> = ({ ev3 }) => {
const colorSensor = ev3.get('colorSensor');
export const ColorSensorPanel: React.FC<{ ev3?: DefaultEv3 }> = ({ ev3 }) => {
const colorSensor = ev3?.get('colorSensor');
const sensorVisionRef = useRef<HTMLDivElement>(null);

const [timing, color] = useFetchFromSimulation(() => {
if (ev3.get('colorSensor') === undefined) {
if (colorSensor === undefined) {
return null;
}
return colorSensor.sense();
}, 1000);

useEffect(() => {
if (sensorVisionRef.current) {
if (colorSensor && sensorVisionRef.current) {
sensorVisionRef.current.replaceChildren(
colorSensor.renderer.getElement()
);
}
}, [timing]);

if (!ev3) {
return <TabWrapper>EV3 not found in context. Did you call saveToContext('ev3', ev3);</TabWrapper>;
}

if (timing === null) {
return <TabWrapper>Loading color sensor</TabWrapper>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const getLogString = (log: LogEntry) => {
};

export const ConsolePanel: React.FC<{
robot_console?: RobotConsole;
robot_console: RobotConsole;
}> = ({ robot_console }) => {
const [timing, logs] = useFetchFromSimulation(() => {
if (robot_console === undefined) {
Expand Down
17 changes: 16 additions & 1 deletion src/tabs/RobotSimulation/components/TabPanels/MotorPidPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,22 @@ const RowStyle: CSSProperties = {
gap: '0.6rem',
};

export const MotorPidPanel: React.FC<{ ev3: DefaultEv3 }> = ({ ev3 }) => {
export const MotorPidPanel: React.FC<{ ev3?: DefaultEv3 }> = ({ ev3 }) => {
if (!ev3) {
return (
<TabWrapper>
EV3 not found in context. Did you call saveToContext('ev3', ev3);
</TabWrapper>
);
}

const leftMotor = ev3.get('leftMotor');
const rightMotor = ev3.get('rightMotor');

if (!leftMotor || !rightMotor) {
return <TabWrapper>Motor not found</TabWrapper>;
}

const onChangeProportional = (value: number) => {
ev3.get('leftMotor').pid.proportionalGain = value;
ev3.get('rightMotor').pid.proportionalGain = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@ import { useFetchFromSimulation } from '../../hooks/fetchFromSimulation';
import { LastUpdated } from './tabComponents/LastUpdated';
import { TabWrapper } from './tabComponents/Wrapper';

export const UltrasonicSensorPanel: React.FC<{ ev3: DefaultEv3 }> = ({
export const UltrasonicSensorPanel: React.FC<{ ev3?: DefaultEv3 }> = ({
ev3,
}) => {
const ultrasonicSensor = ev3.get('ultrasonicSensor');

const ultrasonicSensor = ev3?.get('ultrasonicSensor');
const [timing, distanceSensed] = useFetchFromSimulation(() => {
if (ultrasonicSensor === undefined) {
return null;
}
return ultrasonicSensor.sense();
}, 1000);

if (!ev3) {
return (
<TabWrapper>
EV3 not found in context. Did you call saveToContext('ev3', ev3);
</TabWrapper>
);
}

if (timing === null) {
return <TabWrapper>Loading ultrasonic sensor</TabWrapper>;
}
Expand Down
18 changes: 17 additions & 1 deletion src/tabs/RobotSimulation/components/TabPanels/WheelPidPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,23 @@ const RowStyle: CSSProperties = {
gap: '0.6rem',
};

export const WheelPidPanel: React.FC<{ ev3: DefaultEv3 }> = ({ ev3 }) => {
export const WheelPidPanel: React.FC<{ ev3?: DefaultEv3 }> = ({ ev3 }) => {
if (!ev3) {
return (
<TabWrapper>
EV3 not found in context. Did you call saveToContext('ev3', ev3);
</TabWrapper>
);
}
if (
!ev3.get('backLeftWheel') ||
!ev3.get('backRightWheel') ||
!ev3.get('frontLeftWheel') ||
!ev3.get('frontRightWheel')
) {
return <TabWrapper>Wheel not found</TabWrapper>;
}

const onChangeProportional = (value: number) => {
ev3.get('backLeftWheel').pid.proportionalGain = value;
ev3.get('backRightWheel').pid.proportionalGain = value;
Expand Down

0 comments on commit f7a4cfa

Please sign in to comment.