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>
112 lines
3.7 KiB
C
112 lines
3.7 KiB
C
/*
|
||
* 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.5–1.0s (15–30 frames)
|
||
* - Blink duration: 100–150 ms (3–5 frames)
|
||
* - Blink interval: 4–6 seconds (120–180 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
|