feat: added reset experiment (in UI)

ref:N25B-400
This commit is contained in:
Pim Hutting
2026-01-16 14:25:26 +01:00
parent c4e3ab27b2
commit d8cae9f838
3 changed files with 40 additions and 18 deletions

View File

@@ -2,7 +2,8 @@ import React from 'react';
import styles from './MonitoringPage.module.css'; import styles from './MonitoringPage.module.css';
import useProgramStore from "../../utils/programStore.ts"; import useProgramStore from "../../utils/programStore.ts";
import { GestureControls, SpeechPresets, DirectSpeechInput, StatusList, RobotConnected } from './MonitoringPageComponents.tsx'; import { GestureControls, SpeechPresets, DirectSpeechInput, StatusList, RobotConnected } from './MonitoringPageComponents.tsx';
import { nextPhase, useExperimentLogger, useStatusLogger, pauseExperiment, playExperiment, resetExperiment, resetPhase, type ExperimentStreamData, type GoalUpdate, type TriggerUpdate, type CondNormsStateUpdate, type PhaseUpdate } from ".//MonitoringPageAPI.ts" import { nextPhase, useExperimentLogger, useStatusLogger, pauseExperiment, playExperiment, resetPhase, type ExperimentStreamData, type GoalUpdate, type TriggerUpdate, type CondNormsStateUpdate, type PhaseUpdate } from ".//MonitoringPageAPI.ts"
import { graphReducer, runProgramm } from '../VisProgPage/VisProg.tsx';
import type { NormNodeData } from '../VisProgPage/visualProgrammingUI/nodes/NormNode.tsx'; import type { NormNodeData } from '../VisProgPage/visualProgrammingUI/nodes/NormNode.tsx';
@@ -39,6 +40,8 @@ const MonitoringPage: React.FC = () => {
const getNormsInPhase = useProgramStore((s) => s.getNormsInPhase); const getNormsInPhase = useProgramStore((s) => s.getNormsInPhase);
const getGoalsInPhase = useProgramStore((s) => s.getGoalsInPhase); const getGoalsInPhase = useProgramStore((s) => s.getGoalsInPhase);
const getTriggersInPhase = useProgramStore((s) => s.getTriggersInPhase); const getTriggersInPhase = useProgramStore((s) => s.getTriggersInPhase);
const setProgramState = useProgramStore((state) => state.setProgramState);
// Can be used to block actions until feedback from CB. // Can be used to block actions until feedback from CB.
const [loading, setLoading] = React.useState(false); const [loading, setLoading] = React.useState(false);
@@ -134,6 +137,31 @@ const handleStatusUpdate = React.useCallback((data: any) => {
//For pings that update conditional norms //For pings that update conditional norms
useStatusLogger(handleStatusUpdate); useStatusLogger(handleStatusUpdate);
const resetExperiment = React.useCallback(async () => {
try {
setLoading(true);
const phases = graphReducer();
setProgramState({ phases });
//reset monitoring page
setActiveIds({}); //remove active items
setPhaseIndex(0); //Go to first phase
setGoalIndex(0); // Reset goal indicator
setIsFinished(false); // Reset experiment done
//inform backend
await runProgramm();
console.log("Experiment & UI successfully reset to start.");
} catch (err) {
console.error("Failed to reset program:", err);
} finally {
setLoading(false);
}
}, [graphReducer, setProgramState]);
if (phaseIds.length === 0) { if (phaseIds.length === 0) {
return <p className={styles.empty}>No program loaded.</p>; return <p className={styles.empty}>No program loaded.</p>;
} }
@@ -223,9 +251,6 @@ const handleStatusUpdate = React.useCallback((data: any) => {
case "nextPhase": case "nextPhase":
await nextPhase(); await nextPhase();
break; break;
case "resetPhase":
await resetPhase();
break;
case "resetExperiment": case "resetExperiment":
await resetExperiment(); await resetExperiment();
break; break;
@@ -324,7 +349,7 @@ const handleStatusUpdate = React.useCallback((data: any) => {
{/*Restart Experiment button*/} {/*Restart Experiment button*/}
<button <button
className={styles.restartExperiment} className={styles.restartExperiment}
onClick={() => handleButton("resetExperiment")} onClick={() => resetExperiment()}
disabled={loading} disabled={loading}
> >

View File

@@ -44,21 +44,17 @@ export async function resetPhase(): Promise<void> {
} }
/** /**
* Sends an API call to the CB for going to reset the experiment * Sends an API call to the CB for going to pause experiment
* In case we can't go to the next phase, the function will throw an error. */
*/
export async function resetExperiment(): Promise<void> {
const type = "reset_experiment"
const context = ""
sendAPICall(type, context)
}
export async function pauseExperiment(): Promise<void> { export async function pauseExperiment(): Promise<void> {
const type = "pause" const type = "pause"
const context = "true" const context = "true"
sendAPICall(type, context) sendAPICall(type, context)
} }
/**
* Sends an API call to the CB for going to resume experiment
*/
export async function playExperiment(): Promise<void> { export async function playExperiment(): Promise<void> {
const type = "pause" const type = "pause"
const context = "false" const context = "false"
@@ -111,6 +107,7 @@ export function useExperimentLogger(onUpdate?: (data: ExperimentStreamData) => v
}; };
}, []); }, []);
} }
/** /**
* A hook that listens to the status stream that updates active conditional norms * A hook that listens to the status stream that updates active conditional norms
* via updates sent from the backend * via updates sent from the backend
@@ -131,5 +128,5 @@ export function useStatusLogger(onUpdate?: (data: any) => void) {
} catch (err) { console.warn("Status stream error:", err); } } catch (err) { console.warn("Status stream error:", err); }
}; };
return () => eventSource.close(); return () => eventSource.close();
}, []); // LEGE dependency array }, []);
} }

View File

@@ -144,9 +144,9 @@ function VisualProgrammingUI() {
</ReactFlowProvider> </ReactFlowProvider>
); );
} }
// currently outputs the prepared program to the console // currently outputs the prepared program to the console
function runProgramm() { export function runProgramm() {
const phases = graphReducer(); const phases = graphReducer();
const program = {phases} const program = {phases}
console.log(JSON.stringify(program, null, 2)); console.log(JSON.stringify(program, null, 2));
@@ -170,7 +170,7 @@ function runProgramm() {
/** /**
* Reduces the graph into its phases' information and recursively calls their reducing function * Reduces the graph into its phases' information and recursively calls their reducing function
*/ */
function graphReducer() { export function graphReducer() {
const { nodes } = useFlowStore.getState(); const { nodes } = useFlowStore.getState();
return orderPhaseNodeArray(nodes.filter((n) => n.type == 'phase') as PhaseNode []) return orderPhaseNodeArray(nodes.filter((n) => n.type == 'phase') as PhaseNode [])
.map((n) => { .map((n) => {