nx_haptic_render.nx source
↩ module page · 195 lines · 10242 B
1// nx_haptic_render.nx -- temporal-vibration output rendering.
2//
3// module: nishi-core.perception.haptic_render
4// depends: nishi-core.perception.profile + nishi-core.perception.signal_compensator +
5// nishi-core.perception.transducer_characterizer + nishi-core.io.syscalls
6// disk_kb: 5
7// capability: PERCEPTION
8// wired_status: PARTIAL_WIRED
9//
10// MISSING_CAPABILITIES:
11// - PWM_GENERATOR_DISPATCH (drive haptic motor via MCU PWM peripheral;
12// depends on nx_mcu_pwm primitive from embedded substrate arc)
13// - DAC_VOLTAGE_DISPATCH (for voice-coil / linear-resonant-actuator
14// haptics that take analog drive)
15// - SIGNAL_COMPENSATOR_CALL (route output through nx_signal_compensator
16// with TEMPORAL_VIBRATION domain + per-motor calibration curve)
17// - WAVEFORM_LIBRARY_LOAD (pre-defined haptic patterns: paw-thump,
18// scratch, click, double-tap, prey-step, etc.)
19// - CONCURRENT_VOICE_MIXING (multiple haptic events overlapping in time
20// without phase issues)
21// - SAFETY_LIMITER (prevent motor stall + over-current per
22// [[feedback-cooperative-resource-arbitration-vs-bloatware]])
23//
24// license_tier: PUBLIC_NISHI_SUBSTRATE
25// genealogy_id: feedback-substrate-primitives-meta-not-one-off_2026 +
26// feedback-multi-species-perceptual-substrate-not-anthropocentric_2026 +
27// feedback-substrate-does-heavy-lifting-user-is-partner-not-gate +
28// immersion_2014_TouchSense_haptic_patterns +
29// feedback-build-intelligence-never-strip-features
30//
31// Per cardinals [[feedback-substrate-primitives-meta-not-one-off]] and
32// [[feedback-multi-species-perceptual-substrate-not-anthropocentric]]:
33// THIS primitive renders temporal-vibration output for ANY haptic
34// transducer (ERM = eccentric rotating mass, LRA = linear resonant actuator,
35// voice-coil, piezo bender, solenoid pulse). Per-motor calibration via
36// nx_transducer_characterize(NX_TXR_KIND_VIBRATION_OUTPUT); per-render
37// pre-correction via nx_signal_compensator(NX_SIG_DOMAIN_TEMPORAL_VIBRATION).
38//
39// Reuse set served by this single primitive:
40// - Dog toy paw-thump simulation (prey-spec dog toy)
41// - Working-dog training cue (haptic collar feedback)
42// - Livestock acoustic welfare monitoring (vibration playback for
43// anxiety calming -- bovine vibration acoustics research)
44// - Beekeeping (queen-substitute vibration patterns)
45// - Aquaculture (fish behavioral conditioning via tank-wall vibration)
46// - Vet diagnostics (controlled mechanical stimulus for reflex testing)
47// - Veterinary physical therapy (controlled vibration on muscle)
48// - Human accessibility (haptic notifications when audio + visual fail)
49
50import "nx_syscalls.nx"
51import "nx_perceptual_profile.nx"
52import "nx_signal_compensator.nx"
53import "nx_transducer_characterizer.nx"
54
55// ===== Haptic actuator type sealed enum ===========================
56//
57// Different physical actuators require different drive electronics +
58// drive waveforms. Substrate selects appropriate signal shape per type.
59
60const NX_HAPTIC_ACTUATOR_ERM: i64 = 1 // eccentric rotating mass
61const NX_HAPTIC_ACTUATOR_LRA: i64 = 2 // linear resonant actuator
62const NX_HAPTIC_ACTUATOR_VOICE_COIL: i64 = 3 // small voice-coil motor
63const NX_HAPTIC_ACTUATOR_PIEZO_BENDER: i64 = 4 // piezoelectric bending element
64const NX_HAPTIC_ACTUATOR_SOLENOID_PULSE: i64 = 5 // electromagnetic solenoid
65const NX_HAPTIC_ACTUATOR_BONE_CONDUCTION: i64 = 6 // bone-conduction transducer
66const NX_HAPTIC_ACTUATOR_PLATFORM_SHAKER: i64 = 7 // larger platform, livestock scale
67
68func nx_haptic_actuator_name(a: i64) -> *u8 {
69 if a == NX_HAPTIC_ACTUATOR_ERM { return "ERM" }
70 if a == NX_HAPTIC_ACTUATOR_LRA { return "LRA" }
71 if a == NX_HAPTIC_ACTUATOR_VOICE_COIL { return "VOICE_COIL" }
72 if a == NX_HAPTIC_ACTUATOR_PIEZO_BENDER { return "PIEZO_BENDER" }
73 if a == NX_HAPTIC_ACTUATOR_SOLENOID_PULSE { return "SOLENOID_PULSE" }
74 if a == NX_HAPTIC_ACTUATOR_BONE_CONDUCTION { return "BONE_CONDUCTION" }
75 if a == NX_HAPTIC_ACTUATOR_PLATFORM_SHAKER { return "PLATFORM_SHAKER" }
76 return "UNKNOWN_ACTUATOR"
77}
78
79// ===== Haptic pattern sealed enum =================================
80//
81// Library of pre-defined behavioral haptic patterns. Reusable across
82// products; species-appropriate variations registered later via
83// nx_perceptual_profile selection.
84
85const NX_HAPTIC_PATTERN_PAW_THUMP: i64 = 1 // dog toy: rabbit-thump, single
86const NX_HAPTIC_PATTERN_PAW_THUMP_DOUBLE: i64 = 2 // rabbit-alarm-thump pair
87const NX_HAPTIC_PATTERN_SCRATCH: i64 = 3 // small mammal scratching
88const NX_HAPTIC_PATTERN_PREY_STEP: i64 = 4 // light footfall sequence
89const NX_HAPTIC_PATTERN_PREY_FLIGHT: i64 = 5 // accelerating away-pattern
90 // (reactive prey-flight)
91const NX_HAPTIC_PATTERN_BIRD_LANDING: i64 = 6 // wing-flutter + landing impact
92const NX_HAPTIC_PATTERN_QUEEN_BEE_BUZZ: i64 = 7 // beekeeping
93const NX_HAPTIC_PATTERN_CALMING_PULSE: i64 = 8 // anxiety-reduction rhythm
94const NX_HAPTIC_PATTERN_TRAINING_CUE: i64 = 9 // working-dog training collar
95const NX_HAPTIC_PATTERN_NOTIFICATION: i64 = 10 // human accessibility
96const NX_HAPTIC_PATTERN_USER_DEFINED: i64 = 11 // caller provides waveform
97
98func nx_haptic_pattern_name(p: i64) -> *u8 {
99 if p == NX_HAPTIC_PATTERN_PAW_THUMP { return "PAW_THUMP" }
100 if p == NX_HAPTIC_PATTERN_PAW_THUMP_DOUBLE { return "PAW_THUMP_DOUBLE" }
101 if p == NX_HAPTIC_PATTERN_SCRATCH { return "SCRATCH" }
102 if p == NX_HAPTIC_PATTERN_PREY_STEP { return "PREY_STEP" }
103 if p == NX_HAPTIC_PATTERN_PREY_FLIGHT { return "PREY_FLIGHT" }
104 if p == NX_HAPTIC_PATTERN_BIRD_LANDING { return "BIRD_LANDING" }
105 if p == NX_HAPTIC_PATTERN_QUEEN_BEE_BUZZ { return "QUEEN_BEE_BUZZ" }
106 if p == NX_HAPTIC_PATTERN_CALMING_PULSE { return "CALMING_PULSE" }
107 if p == NX_HAPTIC_PATTERN_TRAINING_CUE { return "TRAINING_CUE" }
108 if p == NX_HAPTIC_PATTERN_NOTIFICATION { return "NOTIFICATION" }
109 if p == NX_HAPTIC_PATTERN_USER_DEFINED { return "USER_DEFINED" }
110 return "UNKNOWN_PATTERN"
111}
112
113// ===== Render verdicts ============================================
114
115const NX_HAPTIC_RENDER_OK: i64 = 0
116const NX_HAPTIC_RENDER_FAIL_BAD_ACTUATOR: i64 = 1
117const NX_HAPTIC_RENDER_FAIL_BAD_PATTERN: i64 = 2
118const NX_HAPTIC_RENDER_FAIL_NOT_CALIBRATED: i64 = 3 // no curve in
119 // nx_provenance_curve_store
120const NX_HAPTIC_RENDER_FAIL_SAFETY_LIMITED: i64 = 4 // would exceed motor limits
121const NX_HAPTIC_RENDER_FAIL_BUSY: i64 = 5 // previous pattern still playing
122const NX_HAPTIC_RENDER_FAIL_DEPENDENCY_MISSING: i64 = 6 // PARTIAL_WIRED default
123
124func nx_haptic_render_verdict_name(v: i64) -> *u8 {
125 if v == NX_HAPTIC_RENDER_OK { return "OK" }
126 if v == NX_HAPTIC_RENDER_FAIL_BAD_ACTUATOR { return "FAIL_BAD_ACTUATOR" }
127 if v == NX_HAPTIC_RENDER_FAIL_BAD_PATTERN { return "FAIL_BAD_PATTERN" }
128 if v == NX_HAPTIC_RENDER_FAIL_NOT_CALIBRATED { return "FAIL_NOT_CALIBRATED" }
129 if v == NX_HAPTIC_RENDER_FAIL_SAFETY_LIMITED { return "FAIL_SAFETY_LIMITED" }
130 if v == NX_HAPTIC_RENDER_FAIL_BUSY { return "FAIL_BUSY" }
131 if v == NX_HAPTIC_RENDER_FAIL_DEPENDENCY_MISSING { return "FAIL_DEPENDENCY_MISSING" }
132 return "UNKNOWN_HAPTIC_RENDER_VERDICT"
133}
134
135// ===== Render parameters struct ===================================
136//
137// Bundled per [[feedback-nishilang-16-arg-function-limit]].
138
139struct NxHapticRenderParams {
140 actuator_kind: i64 // NX_HAPTIC_ACTUATOR_*
141 pattern: i64 // NX_HAPTIC_PATTERN_*
142 intensity_pct: i64 // 0..100 of safe-max
143 duration_ms: i64
144 repeat_count: i64 // 1 = single, N>1 = repeat N times
145 repeat_gap_ms: i64
146 target_species_profile: i64 // for species-appropriate pattern variation
147 actuator_serial_ptr: *u8
148 actuator_serial_len: i64 // identifies which actuator's calibration to load
149 user_defined_waveform_ptr: *u8 // only used when pattern = USER_DEFINED
150 user_defined_waveform_len: i64
151}
152
153// ===== Top-level entry stubs ======================================
154
155// nx_haptic_render_play -- play a haptic pattern through the named
156// actuator. Substrate loads calibration curve from
157// nx_provenance_curve_store, applies inverse-FRF compensation via
158// nx_signal_compensator (TEMPORAL_VIBRATION domain), enforces safety
159// limits, dispatches to MCU peripheral.
160
161func nx_haptic_render_play(params_ptr: *NxHapticRenderParams) -> i64 {
162 if params_ptr == 0 as *NxHapticRenderParams { return NX_HAPTIC_RENDER_FAIL_BAD_PATTERN }
163 // PARTIAL_WIRED: PWM dispatch + signal compensation + waveform library queued.
164 return NX_HAPTIC_RENDER_FAIL_DEPENDENCY_MISSING
165}
166
167// nx_haptic_render_stop -- halt any in-progress haptic playback on the
168// named actuator (e.g., when reactive-flight detects subject retreat).
169
170func nx_haptic_render_stop(actuator_serial_ptr: *u8, actuator_serial_len: i64) -> i64 {
171 if actuator_serial_len <= 0 { return 0 }
172 return 0
173}
174
175// nx_haptic_render_is_busy -- inspector: is this actuator currently
176// playing a pattern? Used by reactive-behavior orchestrator to coordinate.
177
178func nx_haptic_render_is_busy(actuator_serial_ptr: *u8, actuator_serial_len: i64) -> i64 {
179 if actuator_serial_len <= 0 { return 0 }
180 return 0
181}
182
183// nx_haptic_render_get_safety_max_intensity -- inspector: what's the
184// maximum safe intensity for this actuator (from calibration + datasheet)?
185
186func nx_haptic_render_get_safety_max_intensity(actuator_serial_ptr: *u8, actuator_serial_len: i64) -> i64 {
187 if actuator_serial_len <= 0 { return 0 }
188 return 0
189}
190
191// nx_haptic_render_get_last_verdict -- inspector.
192
193func nx_haptic_render_get_last_verdict() -> i64 {
194 return NX_HAPTIC_RENDER_FAIL_DEPENDENCY_MISSING
195}