saltylab-firmware/include/face_animation.h
sl-android 49628bcc61 feat: Add Issue #507 - Face display animations on STM32 LCD
Implements expressive face animations with 5 core emotions (happy/sad/curious/angry/sleeping) and smooth transitions on small LCD displays.

Features:
- State machine with smooth 0.5s emotion transitions (ease-in-out cubic easing)
- Automatic idle blinking (4-6s intervals, 100-150ms duration per blink)
- UART command interface via USART3 @ 115200 (text-based protocol)
- 30Hz target refresh rate via systick integration
- Low-level LCD abstraction supporting monochrome and RGB565
- Rendering primitives: pixel, line (Bresenham), circle (midpoint), filled rect

Architecture:
- face_lcd.h/c: Hardware-agnostic framebuffer & display driver
- face_animation.h/c: Emotion state machine & parameterized face rendering
- face_uart.h/c: UART command parser (HAPPY/SAD/CURIOUS/ANGRY/SLEEP/NEUTRAL/BLINK/STATUS)
- Unit tests (14 test cases): emotion transitions, blinking, rendering, all emotions

Integration:
- main.c: Added includes, initialization (servo_init), systick tick, main loop processing
- Pending: LCD hardware initialization (SPI/I2C config, display controller setup)

Files: 9 new (headers, source, tests, docs), 1 modified (main.c)
Lines: ~1450 total (345 headers, 650 source, 350 tests, 900 docs)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 10:27:36 -05:00

112 lines
3.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* face_animation.h — Face Emotion Renderer for LCD Display
*
* Renders expressive face animations for 5 core emotions:
* - HAPPY: upturned eyes, curved smile
* - SAD: downturned eyes, frown
* - CURIOUS: raised eyebrows, wide eyes, slight tilt
* - ANGRY: downturned brows, narrowed eyes, clenched mouth
* - SLEEPING: closed eyes, relaxed mouth, gentle sway (optional)
*
* HOW IT WORKS:
* - State machine with smooth transitions (easing over N frames)
* - Idle behavior: periodic blinking (duration configurable)
* - Each emotion has parameterized eye/mouth shapes (position, angle, curvature)
* - Transitions interpolate between emotion parameter sets
* - render() draws current state to LCD framebuffer via face_lcd_*() API
* - tick() advances frame counter, handles transitions, triggers blink
*
* ANIMATION SPECS:
* - Frame rate: 30 Hz (via systick)
* - Transition time: 0.51.0s (1530 frames)
* - Blink duration: 100150 ms (35 frames)
* - Blink interval: 46 seconds (120180 frames at 30Hz)
*
* API:
* - face_animation_init() — Initialize state machine
* - face_animation_set_emotion(emotion) — Request state change (with smooth transition)
* - face_animation_tick() — Advance animation by 1 frame (call at 30Hz from systick)
* - face_animation_render() — Draw current face to LCD framebuffer
*/
#ifndef FACE_ANIMATION_H
#define FACE_ANIMATION_H
#include <stdint.h>
#include <stdbool.h>
/* === Emotion Types === */
typedef enum {
FACE_HAPPY = 0,
FACE_SAD = 1,
FACE_CURIOUS = 2,
FACE_ANGRY = 3,
FACE_SLEEPING = 4,
FACE_NEUTRAL = 5, /* Default state */
} face_emotion_t;
/* === Animation Parameters (per emotion) === */
typedef struct {
int16_t eye_x; /* Eye horizontal offset from center (pixels) */
int16_t eye_y; /* Eye vertical offset from center (pixels) */
int16_t eye_open_y; /* Eye open height (pixels) */
int16_t eye_close_y; /* Eye close height (pixels, 0=fully closed) */
int16_t brow_angle; /* Eyebrow angle (-30..+30 degrees, tilt) */
int16_t brow_y_offset; /* Eyebrow vertical offset (pixels) */
int16_t mouth_x; /* Mouth horizontal offset (pixels) */
int16_t mouth_y; /* Mouth vertical offset (pixels) */
int16_t mouth_width; /* Mouth width (pixels) */
int16_t mouth_curve; /* Curvature: >0=smile, <0=frown, 0=neutral */
uint8_t blink_interval_ms; /* Idle blink interval (seconds, in 30Hz ticks) */
} face_params_t;
/* === Public API === */
/**
* Initialize face animation system.
* Sets initial emotion to NEUTRAL, clears blink timer.
*/
void face_animation_init(void);
/**
* Request a state change to a new emotion.
* Triggers smooth transition (easing) over TRANSITION_FRAMES.
*/
void face_animation_set_emotion(face_emotion_t emotion);
/**
* Advance animation by one frame.
* Called by systick ISR at 30 Hz.
* Handles:
* - Transition interpolation
* - Blink timing and rendering
* - Idle animations (sway, subtle movements)
*/
void face_animation_tick(void);
/**
* Render current face state to LCD framebuffer.
* Draws eyes, brows, mouth, and optional idle animations.
* Should be called after face_animation_tick().
*/
void face_animation_render(void);
/**
* Get current emotion (transition-aware).
* Returns the target emotion, or current if transition in progress.
*/
face_emotion_t face_animation_get_emotion(void);
/**
* Trigger a blink immediately (for special events).
* Overrides idle blink timer.
*/
void face_animation_blink_now(void);
/**
* Check if animation is idle (no active transition).
*/
bool face_animation_is_idle(void);
#endif // FACE_ANIMATION_H