Robot Facial Expression Designer¶
Specification¶
The full specification below is extracted from Chapter 8: Adding an OLED Display and Expressive Behaviors.
Type: microsim
**sim-id:** robot-facial-expression-designer<br/>
**Library:** p5.js<br/>
**Status:** Specified
Learning objective: Students will *analyze* (Bloom L4: Analyze) how eye shape, mouth shape, and animation timing combine to communicate a specific robot emotion state, and observe how an expression transition bridges two states.
Canvas: 700x420px, responsive -- recompute the simulated OLED display panel's pixel scale from `windowWidth` in `windowResized()` while keeping its aspect ratio locked to 128:64.
Layout: a simulated monochrome OLED panel (dark background, light drawn pixels, scaled up so individual "pixels" are visible as small squares) showing a robot face built from simple shapes (two eye shapes, one mouth line). Below the panel, four emotion-state buttons: Happy, Curious, Alert, Sleepy.
Controls: `createButton()` elements for each of the four emotion states, switching the displayed face; a `createSlider()` labeled "Transition Speed (ms)" (range 100-1500, default 400) controlling how long the animated morph between two states takes; a `createCheckbox()` labeled "Idle Animation" (default checked) that, when enabled, adds a small continuous eye-drift motion whenever no transition is in progress; a `createButton()` labeled "Blink" that triggers one blink animation regardless of current state.
Interaction: clicking a new emotion-state button animates eye shape and mouth shape smoothly morphing from the current state's parameters to the new state's parameters over the Transition Speed duration, rather than snapping instantly -- demonstrating expression transition directly. Hovering any emotion-state button shows a tooltip with a one-sentence description of that state's eye and mouth shape, matching the surrounding chapter text. Clicking "Blink" plays a blink animation regardless of which state is active, then returns to that state's normal look.
Implementation: p5.js, each emotion state defined as a small parameter object (eye height, eye width, mouth curve amount); transitions computed by linearly interpolating (`lerp()`) between the current and target parameter objects over the transition-speed duration using `millis()`-based timing, then redrawing the simulated pixel grid each frame from the interpolated parameters. Idle animation implemented as a small sine-wave offset added to eye position only when no transition is active.