#pragma once // C API of hexapod_sim.dll: the unchanged robot firmware running against // simulated hardware. Consumed by Unity (Assets/HexapodSim/HexapodSimNative.cs) // and by the headless test (tests/sim_smoke.cpp). // // Conventions: robot body frame, mm and degrees - +X forward, +Y left, +Z up // (same as shared/HexapodProtocol). Per-leg arrays are [leg][joint or xyz] // flattened, leg order as in robot/Config.h, joints coxa/femur/tibia. // // One robot per loaded DLL: its globals are the firmware's globals. To reset // the robot, unload and reload the DLL (Unity does this on every Play). #include #ifdef _WIN32 #define HXSIM_API extern "C" __declspec(dllexport) #else #define HXSIM_API extern "C" __attribute__((visibility("default"))) #endif // Bump whenever a signature or struct below changes; the C# side checks it. #define HXSIM_API_VERSION 6 #define HXSIM_NUM_LEGS 6 // All fields 4 bytes wide so C# can mirror this with LayoutKind.Sequential. typedef struct { int32_t num_legs; float mount_x_mm[HXSIM_NUM_LEGS]; float mount_y_mm[HXSIM_NUM_LEGS]; float mount_angle_deg[HXSIM_NUM_LEGS]; float coxa_mm, femur_mm, tibia_mm; float stance_radius_mm, stance_height_mm; float coxa_min_deg, coxa_max_deg; float femur_min_deg, femur_max_deg; float tibia_min_deg, tibia_max_deg; float control_hz; float leg_clearance_mm; // LEG_CLEARANCE_MM: minimum gap between neighbouring legs' segments float stance_height_range_mm; // CmdPacket.body_height +-1000 moves the height by this much } HxGeometry; typedef struct { int32_t robot_state; // 0 DISARMED, 1 SIT, 2 STAND, 3 WALKING float sit_stand_blend; // 0 sit .. 1 stand int32_t link_ok; // Comms::linkOk() float heading_deg; // robot.ino's open-loop heading estimate float imu_roll_deg; // RobotIMU filter output float imu_pitch_deg; int32_t imu_enabled; // robot-gyro toggle as the robot sees it uint32_t sim_time_ms; uint32_t control_ticks; // loop() passes that ran the control step int32_t stance_mask; // bit i = leg i in stance per the gait engine float pose_reach_scale; // 1 = full commanded body pose; less = scaled down to what the legs can reach float twist_scale; // 1 = walk command as sent; less = slowed to a stride the legs can take float stance_height_mm; // current (rate-limited) standing height: feet below hips } HxStatus; HXSIM_API int32_t hxsim_api_version(void); HXSIM_API int32_t hxsim_packet_size(void); // sizeof(CmdPacket) as compiled HXSIM_API void hxsim_get_geometry(HxGeometry* out); // Hardware present at power-on. Call before hxsim_start(). HXSIM_API void hxsim_set_radio_present(int32_t present); HXSIM_API void hxsim_set_imu_present(int32_t present); HXSIM_API void hxsim_start(void); // runs setup() once // Advances simulated time by dt_us, calling loop() every HXSIM_LOOP_PERIOD_US // like the real busy loop (loop() itself holds the CONTROL_HZ rate). HXSIM_API void hxsim_step(uint32_t dt_us); // Inputs HXSIM_API void hxsim_radio_send(const uint8_t* bytes, int32_t len); // one packet on air HXSIM_API void hxsim_set_ground_tilt(float roll_deg, float pitch_deg); // tilt the world (robot-gyro tests) // The MPU6050 is normally fed from the kinematic body model (SimBody.cpp). // Calling this overrides it with fixed readings from then on. HXSIM_API void hxsim_set_imu(float ax_g, float ay_g, float az_g, float gx_dps, float gy_dps, float gz_dps); HXSIM_API void hxsim_serial_input(const char* bytes, int32_t len); // TEST_SERIAL_INPUT keys // Outputs HXSIM_API int32_t hxsim_serial_output(char* out, int32_t cap); // drains robot Serial prints HXSIM_API void hxsim_get_servos(int32_t* us_18, int32_t* attached_18, uint32_t* writes_18); HXSIM_API void hxsim_get_joints_deg(float* deg_18); // servo pulses decoded through Config.h's per-servo SERVOS table HXSIM_API void hxsim_get_feet_mm(float* xyz_18); // forward kinematics of those angles, body frame HXSIM_API void hxsim_get_status(HxStatus* out); // Kinematic body (SimBody.cpp): the body rests on the support plane of its // feet and grounded feet don't slide. World frame = robot frame at power-on, // ground at z = 0. Any pointer may be null. HXSIM_API void hxsim_get_body(float* pos_mm_3, float* quat_wxyz_4, float* yaw_deg, int32_t* contact_mask);