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
}