using System.Runtime.InteropServices; namespace RobotNet10.RobotApp.MarkerDetection; /// /// C-compatible structs for marker_detection C API interop /// Based on marker_detection_cpp-main/include/marker_detection_c_api.h /// /// /// Unix timestamp with seconds and nanoseconds (md_unix_time_t) /// [StructLayout(LayoutKind.Sequential)] public struct md_unix_time_t { public uint sec; public uint nsec; } /// /// Message header (md_header_t) /// [StructLayout(LayoutKind.Sequential)] public struct md_header_t { public uint seq; public md_unix_time_t stamp; public IntPtr frame_id; // char* - must be allocated and freed } /// /// 2D Pose (md_pose2d_t) /// [StructLayout(LayoutKind.Sequential)] public struct md_pose2d_t { public double x; public double y; public double theta; } /// /// 3D Pose (md_pose_t) /// [StructLayout(LayoutKind.Sequential)] public struct md_pose_t { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public double[] position; // [3] - x, y, z [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public double[] orientation; // [4] - x, y, z, w (quaternion) } /// /// Pose Stamped (md_pose_stamped_t) /// [StructLayout(LayoutKind.Sequential)] public struct md_pose_stamped_t { public md_header_t header; public md_pose_t pose; } /// /// LaserScan message (md_laserscan_t) /// [StructLayout(LayoutKind.Sequential)] public struct md_laserscan_t { public md_header_t header; public float angle_min; public float angle_max; public float angle_increment; public float time_increment; public float scan_time; public float range_min; public float range_max; public IntPtr ranges; // float* - pointer to array public nuint ranges_length; // size_t - number of elements public IntPtr intensities; // float* - pointer to array public nuint intensities_length; // size_t - number of elements } /// /// Rectangle marker options (md_rectangle_marker_options_t) /// [StructLayout(LayoutKind.Sequential)] public struct md_rectangle_marker_options_t { public IntPtr marker_frame_id; // char* - must be allocated and freed public double marker_length; public double marker_width; public double marker_geometric_error; public double marker_intensity_threshold_; public double angle_min_of_scan; public double angle_max_of_scan; public double min_range_of_scan; public double max_range_of_scan; public int use_estimate_marker_pose; // bool public double max_position_error; public double max_yaw_angle_error; public ushort num_filter_samples; public double leg_thickness_offset; public int run_debug; // bool } /// /// Segment marker options (md_segment_marker_options_t) /// [StructLayout(LayoutKind.Sequential)] public struct md_segment_marker_options_t { public IntPtr marker_frame_id; // char* - must be allocated and freed public double marker_length; public double marker_geometric_error; public double marker_intensity_threshold_; public double angle_min_of_scan; public double angle_max_of_scan; public double min_range_of_scan; public double max_range_of_scan; public int use_estimate_marker_pose; // bool public double max_position_error; public double max_yaw_angle_error; public ushort num_filter_samples; public double leg_thickness_offset; public int run_debug; // bool }