using System.Runtime.InteropServices; // using RobotNet10.Shared.Sensor; namespace RobotNet10.RobotApp.Navigation; /// /// P/Invoke declarations for Navigation C API /// public static class NavigationNativeInterface { // Library path private const string LibraryPath = "/usr/local/lib/libnav_c_api.so"; #region String Management /// /// Free a string allocated by the library /// /// String to free [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void nav_c_api_free_string(IntPtr str); #endregion #region State Conversion /// /// Convert a State enum to its string representation /// /// Enum value of NavigationState /// String representation (caller must free with nav_c_api_free_string) [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr navigation_state_to_string(NavigationState state); #endregion #region Header Functions /// /// Create a new header /// /// Frame id /// Header [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Header header_create([MarshalAs(UnmanagedType.LPUTF8Str)] string frame_id); /// /// Set data for a header /// /// Sequence /// Second /// Nanosecond /// Frame id /// Header [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern Header header_set_data( uint seq, uint sec, uint nsec, [MarshalAs(UnmanagedType.LPUTF8Str)] string frame_id); /// /// Create a new time /// /// Time [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern Time time_create(); #endregion #region Helper Functions /// /// Creates a target pose by offsetting a given 2D pose along its heading direction /// /// X coordinate of the original pose /// Y coordinate of the original pose /// Heading angle in radians /// The coordinate frame ID (null-terminated string) /// Distance to offset along heading (positive = forward, negative = backward) /// Output parameter for the offset pose /// true on success, false on failure [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_offset_goal_2d( double pose_x, double pose_y, double pose_theta, [MarshalAs(UnmanagedType.LPUTF8Str)] string frame_id, double offset_distance, out PoseStamped out_goal); /// /// Creates an offset target pose from a given PoseStamped /// /// Input pose /// Distance to offset along heading direction /// Output parameter for the offset pose /// true on success, false on failure [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_offset_goal_stamped( ref PoseStamped in_pose, double offset_distance, out PoseStamped out_goal); #endregion #region Navigation Handle Management /// /// Create a new navigation instance /// /// Navigation handle, or IntPtr.Zero on failure [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr navigation_create(); /// /// Destroy a navigation instance /// /// Navigation handle to destroy [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_destroy(IntPtr handle); #endregion #region TF Listener Management /// /// Create a TF listener instance /// /// TF listener handle, or IntPtr.Zero on failure [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr tf_listener_create(); /// /// Destroy a TF listener instance /// /// TF listener handle to destroy [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void tf_listener_destroy(IntPtr handle); /// /// Inject a static transform into the TF buffer /// /// TF listener handle /// Parent frame id (e.g. "map") /// Child frame id (e.g. "base_link") /// Translation x (meters) /// Translation y (meters) /// Translation z (meters) /// Rotation quaternion x /// Rotation quaternion y /// Rotation quaternion z /// Rotation quaternion w /// true on success, false on failure [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool tf_listener_set_static_transform( IntPtr tf_handle, [MarshalAs(UnmanagedType.LPUTF8Str)] string parent_frame, [MarshalAs(UnmanagedType.LPUTF8Str)] string child_frame, double x, double y, double z, double qx, double qy, double qz, double qw); #endregion #region Navigation Interface Methods /// /// Initialize the navigation system /// /// Navigation handle /// TF listener handle /// true on success, false on failure [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_initialize(IntPtr handle, IntPtr tf_handle); /// /// Set the robot's footprint (outline shape) /// /// Navigation handle /// Array of points representing the footprint polygon /// Number of points in the array /// true on success, false on failure [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_set_robot_footprint( IntPtr handle, IntPtr points, nuint point_count); /// /// Get the robot's footprint (outline shape) /// /// Navigation handle /// Output array of points (allocated by library, free with navigation_free_points) /// Output number of points in the array /// true on success, false on failure [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_get_robot_footprint( IntPtr handle, out IntPtr out_points, out nuint out_count); /// /// Free a points array allocated by navigation_get_robot_footprint /// /// Pointer to point array [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_points(IntPtr points); /// /// Send a goal for the robot to navigate to /// /// Navigation handle /// Target pose in the global frame /// Acceptable error in X/Y (meters) /// Acceptable angular error (radians) /// true if goal was accepted and sent successfully [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_move_to( IntPtr handle, PoseStamped goal); /// /// Send a goal for the robot to navigate to with order /// Note: This function may not be available in all C API versions /// /// Navigation handle /// Order handle /// Target pose in the global frame /// Acceptable error in X/Y (meters) /// Acceptable angular error (radians) /// true if goal was accepted and sent successfully [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_move_to_order(IntPtr handle, Order order, PoseStamped goal); /// /// Send a docking goal to a predefined marker /// /// Navigation handle /// Marker name or ID (null-terminated string) /// Target pose for docking /// Acceptable XY error (meters) /// Acceptable heading error (radians) /// true if docking command succeeded [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_dock_to( IntPtr handle, [MarshalAs(UnmanagedType.LPUTF8Str)] string marker, PoseStamped goal); /// /// Move straight toward the target position /// /// Navigation handle /// Target pose /// Acceptable positional error (meters) /// true if command issued successfully [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_move_straight_to( IntPtr handle, double distance); /// /// Rotate in place to align with target orientation /// /// Navigation handle /// Pose containing desired heading (only Z-axis used) /// Acceptable angular error (radians) /// true if rotation command was sent successfully [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_rotate_to( IntPtr handle, PoseStamped goal); /// /// Pause the robot's movement /// /// Navigation handle [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_pause(IntPtr handle); /// /// Resume motion after a pause /// /// Navigation handle [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_resume(IntPtr handle); /// /// Cancel the current goal and stop the robot /// /// Navigation handle [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_cancel(IntPtr handle); /// /// Send limited linear velocity command /// /// Navigation handle /// Linear velocity in X direction /// Linear velocity in Y direction /// Linear velocity in Z direction /// true if the command was accepted [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_set_twist_linear( IntPtr handle, double linear_x, double linear_y, double linear_z); /// /// Send limited angular velocity command /// /// Navigation handle /// Angular velocity around X axis /// Angular velocity around Y axis /// Angular velocity around Z axis /// true if the command was accepted [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_set_twist_angular( IntPtr handle, double angular_x, double angular_y, double angular_z); /// /// Get the robot's pose as a PoseStamped /// /// Navigation handle /// Output parameter with the robot's current pose /// true if pose was successfully retrieved [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_get_robot_pose_stamped( IntPtr handle, ref PoseStamped out_pose); /// /// Get the robot's pose as a 2D pose /// /// Navigation handle /// Output parameter with the robot's current 2D pose /// true if pose was successfully retrieved [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_get_robot_pose_2d( IntPtr handle, ref Pose2D out_pose); /// /// Get the robot's current twist /// /// Navigation handle /// Output parameter with the robot's current twist /// true if twist was successfully retrieved [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_get_twist( IntPtr handle, ref Twist2DStamped ref_twist); /// /// Get navigation feedback /// /// Navigation handle /// Output parameter with navigation feedback /// true if feedback was successfully retrieved [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_get_feedback( IntPtr handle, ref NavFeedback out_feedback); /// /// Get global planner data from navigation system /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_get_global_data( IntPtr handle, ref PlannerDataOutput out_data); /// /// Get local planner data from navigation system /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_get_local_data( IntPtr handle, ref PlannerDataOutput out_data); /// /// Free navigation feedback structure /// /// Feedback structure to free [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern void navigation_free_feedback(ref NavFeedback feedback); /// /// Free an occupancy grid handle /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_occupancy_grid(IntPtr handle); /// /// Free an occupancy grid update handle /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_occupancy_grid_update(IntPtr handle); /// /// Free a laser scan handle /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_laser_scan(IntPtr handle); /// /// Free an odometry handle /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_odometry(IntPtr handle); /// /// Free a path2d handle /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_path2d(IntPtr handle); /// /// Free a polygon stamped handle /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_polygon_stamped(IntPtr handle); /// /// Free an order handle /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_order(IntPtr handle); /// /// Free an array of named occupancy grids /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_named_occupancy_grids(IntPtr maps, nuint count); /// /// Free an array of named laser scans /// [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] public static extern void navigation_free_named_laser_scans(IntPtr scans, nuint count); // [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] // [return: MarshalAs(UnmanagedType.Bool)] // public static extern void navigation_free_planner_data(PlannerDataOutputHandle handle); /// /// Add a static map to the navigation system /// /// Navigation handle /// Name of the map /// Occupancy grid handle /// true if the map was added successfully [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_add_static_map( IntPtr handle, [MarshalAs(UnmanagedType.LPUTF8Str)] string map_name, OccupancyGrid occupancy_grid); /// /// Add a laser scan to the navigation system /// /// Navigation handle /// Name of the laser scan /// Laser scan handle /// true if the laser scan was added successfully [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_add_laser_scan( IntPtr handle, [MarshalAs(UnmanagedType.LPUTF8Str)] string laser_scan_name, LaserScan laser_scan); /// /// Add an odometry to the navigation system /// /// Navigation handle /// Name of the odometry /// Odometry handle /// true if the odometry was added successfully [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool navigation_add_odometry( IntPtr handle, [MarshalAs(UnmanagedType.LPUTF8Str)] string odometry_name, Odometry odometry); [DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool navigation_dock_to_order( IntPtr handle, Order order, [MarshalAs(UnmanagedType.LPUTF8Str)] string marker, PoseStamped goal); #endregion }