### Build Franka Collision-Free IK Solver Example Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Adds the Franka collision-free IK solver example executable using the `add_example` macro. ```cmake add_example(franka_collision_free_ik_solver_example src/trajectory_optimizer_examples/franka_collision_free_ik_solver_example.cpp) ``` -------------------------------- ### Build Kinematics Example Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Adds the kinematics example executable using the `add_example` macro. ```cmake add_example(kinematics_example src/kinematics_example.cpp) ``` -------------------------------- ### Install Custom cuMotion Logger (C++) Source: https://context7.com/nvidia-isaac/cumotion/llms.txt This C++ snippet demonstrates how to install a custom logger subclass for integration with application-specific logging frameworks. The example routes all cuMotion output to stderr and handles fatal exceptions. ```cpp class MyLogger : public cumotion::Logger { public: std::ostream& log(cumotion::LogLevel level) override { return std::cerr; // route all cuMotion output to stderr } void finalizeLogMessage(cumotion::LogLevel level) override { std::cerr << "\n"; } void handleFatalError() override { throw cumotion::FatalException("Fatal cuMotion error"); } }; auto logger = std::make_shared(); cumotion::SetLogger(logger); cumotion::SetLogger(); // restore default logger ``` -------------------------------- ### Build Franka Trajectory Optimization Example Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Adds the Franka trajectory optimization example (without obstacles) executable using the `add_example` macro. ```cmake add_example(franka_trajectory_optimizer_example src/trajectory_optimizer_examples/franka_trajectory_optimizer_example.cpp) ``` -------------------------------- ### Macro to Add cuMotion Examples Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Defines a macro `add_example` to simplify adding executable examples. It sets up the executable, links against cuMotion, defines the CONTENT_DIR, and adds include directories. It also includes a post-build command for Windows to copy necessary DLLs. ```cmake macro(add_example TARGET SRC) add_executable(${TARGET} ${SRC}) target_link_libraries(${TARGET} PRIVATE cumotion::cumotion) target_compile_definitions(${TARGET} PRIVATE CONTENT_DIR="${CONTENT_DIR}") target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) if(WIN32) # On Windows, it's necessary to copy the cuMotion DLL to the same directory as the executable. add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ COMMAND_EXPAND_LISTS ) endif() endmacro() ``` -------------------------------- ### Build Franka Collision-Free Trajectory Optimization Example Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Adds the Franka collision-free trajectory optimization example (with cuboid obstacles) executable using the `add_example` macro. ```cmake add_example(franka_trajectory_optimizer_obstacle_example src/trajectory_optimizer_examples/franka_trajectory_optimizer_obstacle_example.cpp) ``` -------------------------------- ### Implement RMPflow Reactive Control Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Instantiate a reactive control policy using `create_rmpflow`. This example demonstrates adding obstacles, setting position targets, defining a c-space attractor, and running a reactive control loop with Euler integration. ```python import cumotion import numpy as np robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") world = cumotion.create_world() # Add sphere and box obstacles sphere = cumotion.create_obstacle(cumotion.Obstacle.Type.SPHERE) sphere.set_attribute(cumotion.Obstacle.Attribute.RADIUS, 0.05) world.add_obstacle(sphere, cumotion.Pose3.from_translation(np.array([0.3, 0.0, 0.6]))) box = cumotion.create_obstacle(cumotion.Obstacle.Type.CUBOID) box.set_attribute(cumotion.Obstacle.Attribute.SIDE_LENGTHS, 0.1 * np.ones(3)) world.add_obstacle(box, cumotion.Pose3.from_translation(np.array([0.4, 0.0, 0.2]))) world_view = world.add_world_view() # Create RMPflow from config file rmpflow_config = cumotion.create_rmpflow_config_from_file( "franka_rmpflow_config.yaml", robot_description, world_view ) rmpflow = cumotion.create_rmpflow(rmpflow_config) # Add end-effector target frame rmpflow.add_target_frame("right_gripper") rmpflow.set_position_target("right_gripper", np.array([0.8, 0.0, 0.35])) # Set c-space attractor (biases toward a "rest" configuration) rmpflow.set_cspace_attractor(robot_description.default_cspace_configuration()) # Reactive control loop (Euler integration, dt = 10 ms) q = np.zeros(7) dq = np.zeros(7) ddq = np.zeros(7) dt = 0.01 for step in range(500): # Move target in sinusoidal pattern target_pos = np.array([0.8, 0.5 * np.sin(0.5 * step * dt), 0.35]) rmpflow.set_position_target("right_gripper", target_pos) # Evaluate c-space acceleration from current state rmpflow.eval_accel(q, dq, ddq) # Update world view (low overhead if obstacles haven't moved) world_view.update() # Integrate q += dt * dq dq += dt * ddq print(f"Final joint position: {q}") ``` -------------------------------- ### Configure and Solve Inverse Kinematics Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Configure IK solver parameters like tolerances and maximum descents. The results provide success status, actual errors, and descent count. ```python config = cumotion.IkConfig() config.max_num_descents = 100 # max number of CCD+BFGS attempts config.position_tolerance = 1e-3 # 1 mm position tolerance config.orientation_tolerance = 0.01 # ~0.57 deg orientation tolerance config.cspace_seeds = [] # optional warm-start seeds # Solve IK results = cumotion.solve_ik(kinematics, target_pose, "right_gripper", config) if results.success: q = results.cspace_position # numpy array, shape (7,) print(f"IK succeeded in {results.num_descents} descent(s)") print(f"Position error: {results.position_error * 1000:.3f} mm") print(f"Orientation error (x/y/z axes): " f"{results.x_axis_orientation_error:.5f} / " f"{results.y_axis_orientation_error:.5f} / " f"{results.z_axis_orientation_error:.5f} rad") # Warm-start next IK call with current solution config.cspace_seeds = [q] results2 = cumotion.solve_ik(kinematics, target_pose, "right_gripper", config) else: print("IK failed to find a solution") ``` -------------------------------- ### Create GPU-Accelerated Collision-Free IK Solver Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Use `create_collision_free_ik_solver` to find IK solutions that avoid self-collisions and world obstacles. Configure tolerances and number of seeds for the solver. ```python import cumotion import numpy as np robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") world = cumotion.create_world() # Add an obstacle box = cumotion.create_obstacle(cumotion.Obstacle.Type.CUBOID) box.set_attribute(cumotion.Obstacle.Attribute.SIDE_LENGTHS, np.array([0.2, 0.2, 0.4])) world.add_obstacle(box, cumotion.Pose3.from_translation(np.array([0.4, 0.0, 0.3]))) world_view = world.add_world_view() config = cumotion.create_default_collision_free_ik_solver_config( robot_description, "right_gripper", world_view ) config.set_param("num_seeds", 32) config.set_param("task_space_position_tolerance", 1e-3) # 1 mm config.set_param("task_space_orientation_tolerance", 5e-3) # ~0.29 deg solver = cumotion.create_collision_free_ik_solver(config) # Single target IK trans = cumotion.CollisionFreeIkSolver.TranslationConstraint.target(np.array([0.5, 0.2, 0.4])) ori = cumotion.CollisionFreeIkSolver.OrientationConstraint.none() task_target = cumotion.CollisionFreeIkSolver.TaskSpaceTarget(trans, ori) results = solver.solve(task_target) Status = cumotion.CollisionFreeIkSolver.Results.Status if results.status() == Status.SUCCESS: solutions = results.c_space_positions() # list of numpy arrays, ordered by cost print(f"Found {len(solutions)} collision-free IK solution(s)") best_q = solutions[0] ``` -------------------------------- ### Create and Manage World Obstacles Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Create a world environment and add various obstacle types like cuboids and spheres. Obstacles can be dynamically enabled, disabled, or have their poses updated at runtime. ```python import cumotion import numpy as np # Create an empty world world = cumotion.create_world() # Add a box obstacle (cuboid) box = cumotion.create_obstacle(cumotion.Obstacle.Type.CUBOID) box.set_attribute(cumotion.Obstacle.Attribute.SIDE_LENGTHS, np.array([0.4, 1.5, 0.02])) box_pose = cumotion.Pose3.from_translation(np.array([0.55, 0.0, 0.6])) box_handle = world.add_obstacle(box, box_pose) # Add a sphere obstacle sphere = cumotion.create_obstacle(cumotion.Obstacle.Type.SPHERE) sphere.set_attribute(cumotion.Obstacle.Attribute.RADIUS, 0.05) sphere_pose = cumotion.Pose3.from_translation(np.array([0.3, 0.0, 0.6])) sphere_handle = world.add_obstacle(sphere, sphere_pose) # Create a world view (snapshot used by planners/controllers) world_view = world.add_world_view() # Enable/disable obstacles dynamically world.disable_obstacle(sphere_handle) world.enable_obstacle(sphere_handle) # Update obstacle pose at runtime new_pose = cumotion.Pose3.from_translation(np.array([0.4, 0.1, 0.5])) world.set_pose(sphere_handle, new_pose) # Commit changes to the world view before next planning call world_view.update() # Remove obstacle permanently world.remove_obstacle(sphere_handle) ``` -------------------------------- ### Forward Kinematics and Jacobians Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Provides forward kinematics queries for any frame in the kinematic structure at a given configuration space position. This includes calculating the full pose, position, orientation, and Jacobians. ```APIDOC ## Kinematics ### Description Provides forward kinematics queries — pose, position, orientation, and Jacobians — for any frame in the kinematic structure at a given configuration space position. ### Method ```python kinematics: Kinematics ``` ### Functions * **pose(q: np.ndarray, frame_name: str) -> Pose3**: Computes the full pose (position and rotation) of a specified frame. * **position(q: np.ndarray, frame_name: str) -> np.ndarray**: Computes the position of a specified frame. * **orientation(q: np.ndarray, frame_name: str) -> Rotation3**: Computes the orientation of a specified frame. * **jacobian(q: np.ndarray, frame_name: str) -> np.ndarray**: Computes the 6xN Jacobian matrix for a specified frame. * **position_jacobian(q: np.ndarray, frame_name: str) -> np.ndarray**: Computes the 3xN translational Jacobian matrix. * **orientation_jacobian(q: np.ndarray, frame_name: str) -> np.ndarray**: Computes the 3xN rotational Jacobian matrix. * **within_cspace_limits(q: np.ndarray, log_warnings: bool = False) -> bool**: Checks if a given configuration is within the robot's joint limits. * **cspace_coord_limits(joint_index: int) -> Limits**: Retrieves the joint limits for a specific joint. * **cspace_coord_velocity_limit(joint_index: int) -> float**: Retrieves the velocity limit for a specific joint. ### Parameters * **q** (np.ndarray) - The configuration space vector. * **frame_name** (str) - The name of the frame for which to compute kinematics. * **joint_index** (int) - The index of the joint. * **log_warnings** (bool) - Whether to log warnings for out-of-limit configurations. ### Returns * **Pose3**: The pose of the frame. * **np.ndarray**: The position or Jacobian matrix. * **Rotation3**: The orientation of the frame. * **bool**: True if the configuration is within limits, False otherwise. * **Limits**: An object containing the lower and upper limits of a joint. * **float**: The velocity limit of a joint. ### Request Example ```python import cumotion import numpy as np from math import pi robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") kinematics = robot_description.kinematics() q = np.array([0.0, -pi/4, 0.0, -3*pi/4, 0.0, pi/2, pi/4]) tool_pose = kinematics.pose(q, "right_gripper") print(f"End-effector position: {tool_pose.translation}") print(f"End-effector rotation: {tool_pose.rotation}") pos = kinematics.position(q, "right_gripper") print(f"Position: {pos}") rot = kinematics.orientation(q, "right_gripper") J = kinematics.jacobian(q, "right_gripper") print(f"Jacobian shape: {J.shape}") in_limits = kinematics.within_cspace_limits(q, log_warnings=True) print(f"Configuration within limits: {in_limits}") for i in range(kinematics.num_cspace_coords()): limits = kinematics.cspace_coord_limits(i) vel_lim = kinematics.cspace_coord_velocity_limit(i) print(f" Joint {i}: [{limits.lower:.2f}, {limits.upper:.2f}] rad, vel_limit={vel_lim:.2f} rad/s") ``` ``` -------------------------------- ### Inverse Kinematics (IK) Solver Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Solves inverse kinematics using a combined CCD + BFGS algorithm to find a joint configuration for a target end-effector pose. Requires a robot description and kinematics object. ```python import cumotion import numpy as np from math import pi robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") kinematics = robot_description.kinematics() # Define target pose for the end-effector orientation = cumotion.Rotation3.from_axis_angle(np.array([0.0, 1.0, 0.0]), pi / 2) target_pose = cumotion.Pose3(orientation, np.array([0.5, 0.0, 0.6])) ``` -------------------------------- ### Load Robot Description from Files Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Loads a robot's kinematic and semantic properties from XRDF and URDF files. Inspect properties like DOF, joint names, and tool frames. Retrieves the default joint configuration and kinematics object. ```python import cumotion import numpy as np # Load robot from XRDF (semantic properties) and URDF (kinematics) robot_description = cumotion.load_robot_from_file( "/path/to/franka.xrdf", "/path/to/franka.urdf" ) # Inspect robot properties print(f"DOF: {robot_description.num_cspace_coords()}") # e.g. 7 for i in range(robot_description.num_cspace_coords()): print(f" Joint {i}: {robot_description.cspace_coord_name(i)}") print(f"Tool frames: {robot_description.tool_frame_names()}") # e.g. ['right_gripper', ...] # Get default joint configuration q_default = robot_description.default_cspace_configuration() # numpy array of shape (7,) print(f"Default config: {q_default}") # Get kinematics object kinematics = robot_description.kinematics() ``` -------------------------------- ### Query cuMotion Library Version (C++) Source: https://context7.com/nvidia-isaac/cumotion/llms.txt This C++ snippet shows how to query the cuMotion library version string. ```cpp // Query library version std::string ver = cumotion::VersionString(); std::cout << "cuMotion version: " << ver << "\n"; ``` -------------------------------- ### Define _USE_MATH_DEFINES for Windows Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Adds the _USE_MATH_DEFINES preprocessor definition, which is required on Windows to use math constants like M_PI. ```cmake if(MSVC) # Required to use math constants (e.g., `M_PI`) on Windows. add_compile_definitions(_USE_MATH_DEFINES) endif() ``` -------------------------------- ### create_collision_free_ik_solver Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Solves Inverse Kinematics (IK) while avoiding self-collision and world obstacles using GPU-accelerated PBO + L-BFGS, returning multiple ranked solutions. ```APIDOC ## create_collision_free_ik_solver / CreateCollisionFreeIkSolver ### Description Uses GPU-accelerated PBO + L-BFGS to solve IK while simultaneously avoiding self-collision and world obstacles, returning multiple ranked solutions. ### Method Signature ```python create_collision_free_ik_solver(config: CollisionFreeIkSolverConfig) ``` ### Parameters - **config** (CollisionFreeIkSolverConfig) - Configuration object for the collision-free IK solver. ### Usage Example ```python import cumotion import numpy as np robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") world = cumotion.create_world() # Add an obstacle box = cumotion.create_obstacle(cumotion.Obstacle.Type.CUBOID) box.set_attribute(cumotion.Obstacle.Attribute.SIDE_LENGTHS, np.array([0.2, 0.2, 0.4])) world.add_obstacle(box, cumotion.Pose3.from_translation(np.array([0.4, 0.0, 0.3]))) world_view = world.add_world_view() config = cumotion.create_default_collision_free_ik_solver_config( robot_description, "right_gripper", world_view ) config.set_param("num_seeds", 32) config.set_param("task_space_position_tolerance", 1e-3) # 1 mm config.set_param("task_space_orientation_tolerance", 5e-3) # ~0.29 deg solver = cumotion.create_collision_free_ik_solver(config) # Single target IK trans = cumotion.CollisionFreeIkSolver.TranslationConstraint.target(np.array([0.5, 0.2, 0.4])) ori = cumotion.CollisionFreeIkSolver.OrientationConstraint.none() task_target = cumotion.CollisionFreeIkSolver.TaskSpaceTarget(trans, ori) results = solver.solve(task_target) Status = cumotion.CollisionFreeIkSolver.Results.Status if results.status() == Status.SUCCESS: solutions = results.c_space_positions() # list of numpy arrays, ordered by cost print(f"Found {len(solutions)} collision-free IK solution(s)") best_q = solutions[0] ``` ``` -------------------------------- ### Loading a Robot Description Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Loads a robot's kinematic and semantic properties from XRDF and URDF files. It returns a RobotDescription object that can be used to query robot properties and access its kinematics. ```APIDOC ## load_robot_from_file ### Description Loads a robot from XRDF (semantic properties) and URDF (kinematics) files, returning a `RobotDescription` that encapsulates all kinematic and semantic properties including joint names, limits, default configurations, and tool frames. ### Method ```python cumotion.load_robot_from_file(xrdf_path: str, urdf_path: str) -> RobotDescription ``` ### Parameters * **xrdf_path** (str) - Path to the XRDF file. * **urdf_path** (str) - Path to the URDF file. ### Returns * **RobotDescription** - An object containing the robot's properties. ### Request Example ```python import cumotion robot_description = cumotion.load_robot_from_file( "/path/to/franka.xrdf", "/path/to/franka.urdf" ) print(f"DOF: {robot_description.num_cspace_coords()}") for i in range(robot_description.num_cspace_coords()): print(f" Joint {i}: {robot_description.cspace_coord_name(i)}") print(f"Tool frames: {robot_description.tool_frame_names()}") q_default = robot_description.default_cspace_configuration() print(f"Default config: {q_default}") kinematics = robot_description.kinematics() ``` ``` -------------------------------- ### Collision-Aware Motion Planning Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Create a GPU-accelerated RRT-Connect planner. Plan paths to c-space or task-space targets, with options for generating interpolated paths and checking for self-collision and world-collision. ```python import cumotion import numpy as np robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") world = cumotion.create_world() # Add box obstacles box = cumotion.create_obstacle(cumotion.Obstacle.Type.CUBOID) box.set_attribute(cumotion.Obstacle.Attribute.SIDE_LENGTHS, np.array([0.02, 1.5, 0.3])) world.add_obstacle(box, cumotion.Pose3.from_translation(np.array([0.35, 0.0, 0.1]))) world_view = world.add_world_view() # Create motion planner from file-based config config = cumotion.create_motion_planner_config_from_file( "franka_planner_config.yaml", robot_description, "panda_leftfingertip", # tool frame name world_view ) # Or with defaults: # config = cumotion.create_default_motion_planner_config(robot_description, "panda_leftfingertip", world_view) planner = cumotion.create_motion_planner(config) q0 = np.array([0.0, 0.0, 0.0, -1.0, 0.0, 1.5, 0.0]) q_target = np.array([0.0, 1.0, 0.0, -1.0, 0.0, 1.5, 0.0]) # Plan to c-space target result = planner.plan_to_cspace_target(q0, q_target, generate_interpolated_path=True) if result.path_found: print(f"Path found with {len(result.path)} knots") for q in result.interpolated_path: pass # execute each waypoint on the robot # Plan to task-space translation target kinematics = robot_description.kinematics() translation_target = kinematics.pose(q_target, "panda_leftfingertip").translation result2 = planner.plan_to_translation_target(q0, translation_target, generate_interpolated_path=True) if result2.path_found: print(f"Task-space path found with {len(result2.path)} knots") # Plan to task-space pose target (position + orientation) pose_target = kinematics.pose(q_target, "panda_leftfingertip") result3 = planner.plan_to_pose_target(q0, pose_target) print(f"Pose target path found: {result3.path_found}") # Reset planner state for deterministic replanning planner.reset() ``` -------------------------------- ### Query cuMotion Library Version (Python) Source: https://context7.com/nvidia-isaac/cumotion/llms.txt This Python snippet shows how to query the cuMotion library version string. ```python print(f"cuMotion version: {cumotion.version_string()}") ``` -------------------------------- ### Set C++ Standard and Required Version Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Configures the C++ standard to C++17 and ensures it is required for the project. ```cmake set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) ``` -------------------------------- ### Inverse Kinematics (IK) Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Solves inverse kinematics using a combined CCD + BFGS algorithm. It returns the joint configuration that places a specified frame at a target pose. ```APIDOC ## solve_ik / SolveIk ### Description Solves inverse kinematics using a combined CCD + BFGS algorithm, returning the joint configuration that places a specified frame at a target pose. ### Method ```python kinematics.solve_ik(target_pose: Pose3, frame_name: str, initial_guess: Optional[np.ndarray] = None) -> np.ndarray ``` ### Parameters * **target_pose** (Pose3) - The desired target pose for the frame. * **frame_name** (str) - The name of the frame to solve for. * **initial_guess** (Optional[np.ndarray]) - An optional initial guess for the joint configuration. ### Returns * **np.ndarray** - The joint configuration that achieves the target pose. ### Request Example ```python import cumotion import numpy as np from math import pi robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") kinematics = robot_description.kinematics() orientation = cumotion.Rotation3.from_axis_angle(np.array([0.0, 1.0, 0.0]), pi / 2) target_pose = cumotion.Pose3(orientation, np.array([0.5, 0.0, 0.6])) # Assuming 'right_gripper' is a valid frame name # solution_q = kinematics.solve_ik(target_pose, "right_gripper") # print(f"IK solution: {solution_q}") ``` ``` -------------------------------- ### Create GPU-Accelerated Trajectory Optimizer Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Use `create_trajectory_optimizer` to generate collision-free, dynamically feasible trajectories. Configure parameters like collision checking and optimization seeds for desired performance. ```python import cumotion import numpy as np robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") kinematics = robot_description.kinematics() world = cumotion.create_world() world_view = world.add_world_view() # Create trajectory optimizer with default config config = cumotion.create_default_trajectory_optimizer_config( robot_description, "right_gripper", world_view ) # Tune optimizer parameters config.set_param("enable_self_collision", True) config.set_param("enable_world_collision", True) config.set_param("ik/num_seeds", 32) config.set_param("trajopt/num_seeds", 4) config.set_param("trajopt/num_knots_per_trajectory", 32) optimizer = cumotion.create_trajectory_optimizer(config) # Define starting configuration and target q_initial = robot_description.default_cspace_configuration() target_position = np.array([0.3, 0.1, 0.1]) # Constraints: target position at termination, unconstrained orientation translation_constraint = cumotion.TrajectoryOptimizer.TranslationConstraint.target(target_position) orientation_constraint = cumotion.TrajectoryOptimizer.OrientationConstraint.none() task_space_target = cumotion.TrajectoryOptimizer.TaskSpaceTarget( translation_constraint, orientation_constraint ) # Optimize trajectory results = optimizer.plan_to_task_space_target(q_initial, task_space_target) Status = cumotion.TrajectoryOptimizer.Results.Status if results.status() == Status.SUCCESS: traj = results.trajectory() domain = traj.domain() print(f"Duration: {domain.span():.2f} s") # Evaluate at any time in [domain.lower, domain.upper] q_end = traj.eval(domain.upper) final_pos = kinematics.position(q_end, "right_gripper") print(f"Final position error: {np.linalg.norm(final_pos - target_position)*1000:.2f} mm") # C-space target with linear path constraint (keeps end-effector on a straight line) q_goal = np.array([0.0, 1.0, 0.0, -1.0, 0.0, 1.5, 0.0]) linear_translation = cumotion.TrajectoryOptimizer.TranslationConstraint.linear_path_constraint( kinematics.pose(q_goal, "right_gripper").translation ) cspace_target = cumotion.TrajectoryOptimizer.CSpaceTarget(q_goal) result2 = optimizer.plan_to_cspace_target(q_initial, cspace_target) print(f"C-space target status: {result2.status()}") else: print(f"Optimization failed: {results.status()}") ``` -------------------------------- ### Extract cuMotion Package on Linux Source: https://github.com/nvidia-isaac/cumotion/blob/main/README.md Use this command to extract the downloaded cuMotion package on Linux systems. Ensure you replace placeholders with your specific version, CUDA version, and architecture. ```bash tar xzvf cumotion---.tar.gz && \ cd cumotion---- ``` -------------------------------- ### create_trajectory_optimizer Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Generates collision-free, dynamically feasible trajectories with flexible task-space constraints using GPU-accelerated PBO + L-BFGS. ```APIDOC ## create_trajectory_optimizer / CreateTrajectoryOptimizer ### Description Uses GPU-accelerated PBO (Particle-Based Optimizer) + L-BFGS to generate collision-free, dynamically feasible trajectories with flexible task-space constraints. ### Method Signature ```python create_trajectory_optimizer(config: TrajectoryOptimizerConfig) ``` ### Parameters - **config** (TrajectoryOptimizerConfig) - Configuration object for the trajectory optimizer. ### Usage Example ```python import cumotion import numpy as np robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") kinematics = robot_description.kinematics() world = cumotion.create_world() world_view = world.add_world_view() # Create trajectory optimizer with default config config = cumotion.create_default_trajectory_optimizer_config( robot_description, "right_gripper", world_view ) # Tune optimizer parameters config.set_param("enable_self_collision", True) config.set_param("enable_world_collision", True) config.set_param("ik/num_seeds", 32) config.set_param("trajopt/num_seeds", 4) config.set_param("trajopt/num_knots_per_trajectory", 32) optimizer = cumotion.create_trajectory_optimizer(config) # Define starting configuration and target q_initial = robot_description.default_cspace_configuration() target_position = np.array([0.3, 0.1, 0.1]) # Constraints: target position at termination, unconstrained orientation translation_constraint = cumotion.TrajectoryOptimizer.TranslationConstraint.target(target_position) orientation_constraint = cumotion.TrajectoryOptimizer.OrientationConstraint.none() task_space_target = cumotion.TrajectoryOptimizer.TaskSpaceTarget( translation_constraint, orientation_constraint ) # Optimize trajectory results = optimizer.plan_to_task_space_target(q_initial, task_space_target) Status = cumotion.TrajectoryOptimizer.Results.Status if results.status() == Status.SUCCESS: traj = results.trajectory() domain = traj.domain() print(f"Duration: {domain.span():.2f} s") # Evaluate at any time in [domain.lower, domain.upper] q_end = traj.eval(domain.upper) final_pos = kinematics.position(q_end, "right_gripper") print(f"Final position error: {np.linalg.norm(final_pos - target_position)*1000:.2f} mm") # C-space target with linear path constraint (keeps end-effector on a straight line) q_goal = np.array([0.0, 1.0, 0.0, -1.0, 0.0, 1.5, 0.0]) linear_translation = cumotion.TrajectoryOptimizer.TranslationConstraint.linear_path_constraint( kinematics.pose(q_goal, "right_gripper").translation ) cspace_target = cumotion.TrajectoryOptimizer.CSpaceTarget(q_goal) result2 = optimizer.plan_to_cspace_target(q_initial, cspace_target) print(f"C-space target status: {result2.status()}") else: print(f"Optimization failed: {results.status()}") ``` ``` -------------------------------- ### Forward Kinematics and Jacobians Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Performs forward kinematics queries for pose, position, orientation, and Jacobians at a given configuration. Checks if the configuration is within joint limits and retrieves individual joint limits and velocity limits. ```python import cumotion import numpy as np from math import pi robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") kinematics = robot_description.kinematics() # Define a joint configuration (7-DOF Franka) q = np.array([0.0, -pi/4, 0.0, -3*pi/4, 0.0, pi/2, pi/4]) # Forward kinematics: full pose (position + rotation) tool_pose = kinematics.pose(q, "right_gripper") print(f"End-effector position: {tool_pose.translation}") # [x, y, z] in meters print(f"End-effector rotation: {tool_pose.rotation}") # Position only pos = kinematics.position(q, "right_gripper") print(f"Position: {pos}") # Orientation only rot = kinematics.orientation(q, "right_gripper") # 6xN Jacobian (first 3 rows: translational, last 3 rows: rotational) J = kinematics.jacobian(q, "right_gripper") # shape (6, 7) J_pos = kinematics.position_jacobian(q, "right_gripper") # shape (3, 7) J_ori = kinematics.orientation_jacobian(q, "right_gripper") # shape (3, 7) print(f"Jacobian shape: {J.shape}") # Check joint limits in_limits = kinematics.within_cspace_limits(q, log_warnings=True) print(f"Configuration within limits: {in_limits}") # Query limits for each joint for i in range(kinematics.num_cspace_coords()): limits = kinematics.cspace_coord_limits(i) vel_lim = kinematics.cspace_coord_velocity_limit(i) print(f" Joint {i}: [{limits.lower:.2f}, {limits.upper:.2f}] rad, vel_limit={vel_lim:.2f} rad/s") ``` -------------------------------- ### Generate Collision Spheres from Mesh Source: https://context7.com/nvidia-isaac/cumotion/llms.txt This Python snippet demonstrates how to load mesh geometry, create a collision sphere generator, and generate spheres approximating the mesh volume. It also shows how to write the sphere data to a YAML file. ```python mesh = o3d.io.read_triangle_mesh("panda_link3.obj") vertices = np.asarray(mesh.vertices) # shape (N, 3) triangles = np.asarray(mesh.triangles) # shape (M, 3) # Create generator from mesh vertices and triangle indices generator = cumotion.create_collision_sphere_generator(vertices, triangles) # Generate spheres approximating the mesh volume num_spheres = 10 # desired number of spheres radius_offset = 0.005 # 5 mm outward expansion (positive = conservative) spheres = generator.generate_spheres(num_spheres, radius_offset) print(f"Generated {len(spheres)} collision spheres:") for i, s in enumerate(spheres): print(f" Sphere {i}: center={s.center}, radius={s.radius:.4f} m") # Write sphere data to XRDF-compatible YAML format with open("link3_collision_spheres.yaml", "w") as f: f.write("collision_spheres:\n - panda_link3:\n") for s in spheres: f.write(f" - center: [{s.center[0]}, {s.center[1]}, {s.center[2]}]\n") f.write(f" radius: {s.radius}\n") ``` -------------------------------- ### Find cuMotion Library Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Finds the cuMotion library if this project is the top-level project. It reports whether cuMotion was found and its directory. ```cmake if(PROJECT_IS_TOP_LEVEL) find_package(cumotion REQUIRED) if(cumotion_FOUND) message(STATUS "cuMotion found at ${cumotion_DIR}") else() message(STATUS "cuMotion not found!") endif() endif() ``` -------------------------------- ### Solve Multiple IK Targets Simultaneously with Batch IK Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Use `CollisionFreeIkSolver.solve_array` to solve multiple IK problems in parallel. Ensure `trans_array` and `ori_array` are correctly structured for batch processing. ```python targets_positions = [np.array([0.4, y, 0.5]) for y in np.linspace(-0.3, 0.3, 5)] trans_array = cumotion.CollisionFreeIkSolver.TranslationConstraintArray.target( [[pos] for pos in targets_positions] # outer dim = problems, inner = constraints per problem ) ori_array = cumotion.CollisionFreeIkSolver.OrientationConstraintArray.none() target_array = cumotion.CollisionFreeIkSolver.TaskSpaceTargetArray(trans_array, ori_array) batch_results = solver.solve_array(target_array) print(f"Solved {batch_results.num_successes()} / {batch_results.num_problems()} batch IK problems") for i in range(batch_results.num_problems()): r = batch_results.problem(i) print(f" Problem {i}: {'SUCCESS' if r.status() == Status.SUCCESS else 'FAILED'}") ``` -------------------------------- ### Find CUDA Toolkit and Set Compiler Path Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Finds the CUDA toolkit and explicitly sets the path to the NVCC compiler. It also dynamically sets CUDA architectures based on the detected CUDA version and system processor. ```cmake find_package(CUDAToolkit 12.2 REQUIRED) set(CMAKE_CUDA_COMPILER "/usr/local/cuda/bin/nvcc" CACHE FILEPATH "Filepath to nvcc compiler, default installation path provided") if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) # Enable Blackwell if supported by CUDA toolkit. set(ENABLE_BLACKWELL OFF) if(${CUDAToolkit_VERSION} VERSION_GREATER_EQUAL 12.8) set(ENABLE_BLACKWELL ON) endif() message(STATUS "CUDA Toolkit VERSION: ${CUDAToolkit_VERSION}. Supports Blackwell? ${ENABLE_BLACKWELL}") if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") set(CMAKE_CUDA_ARCHITECTURES 87) # Jetson Orin if(${ENABLE_BLACKWELL}) list(APPEND CMAKE_CUDA_ARCHITECTURES 110) # Jetson Thor (Blackwell) list(APPEND CMAKE_CUDA_ARCHITECTURES 121) # DGX Spark (GB10) endif() else() set(CMAKE_CUDA_ARCHITECTURES "75;86;89") # Turing (TU10x), Ampere (GA10x), and Ada (AD10x) if(${ENABLE_BLACKWELL}) list(APPEND CMAKE_CUDA_ARCHITECTURES 120) # Blackwell (GB20x) endif() endif() endif() enable_language(CUDA) ``` -------------------------------- ### Set cuMotion Log Level (C++) Source: https://context7.com/nvidia-isaac/cumotion/llms.txt This C++ snippet shows how to set the verbosity of cuMotion's built-in logger. Use WARNING to suppress INFO and VERBOSE messages. ```cpp #include "cumotion/cumotion.h" #include #include // --- Set log level (C++) --- cumotion::SetLogLevel(cumotion::LogLevel::WARNING); // default; suppress INFO and VERBOSE ``` -------------------------------- ### Generate Time-Optimal Trajectories Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Use `create_cspace_trajectory_generator` to compute time-optimal, smooth trajectories through joint-space waypoints. This function respects velocity, acceleration, and jerk limits. ```python import cumotion import numpy as np robot_description = cumotion.load_robot_from_file("franka.xrdf", "franka.urdf") kinematics = robot_description.kinematics() # Create generator seeded from robot kinematics (inherits joint limits automatically) traj_gen = cumotion.create_cspace_trajectory_generator(kinematics) # Define joint-space waypoints (7-DOF Franka) waypoints = [ np.array([0.0, 0.0, 0.0, -0.1, 0.0, 0.0, 0.0]), np.array([0.5, 0.2, -0.5, -1.2, 0.5, 1.3, 0.5]), np.array([0.0, 0.1, 1.5, -2.0, 0.1, 2.2, 0.5]), np.array([0.7, 0.8, 0.5, -0.5, 0.0, 1.2, 0.5]), np.array([1.0, 1.2, -2.1, -2.5, 1.3, 2.4,-0.5]), ] # Generate time-optimal trajectory trajectory = traj_gen.generate_trajectory(waypoints) domain = trajectory.domain() print(f"Trajectory duration: {domain.span():.3f} s") # Evaluate trajectory at arbitrary time points num_samples = 100 for t in np.linspace(domain.lower, domain.upper, num_samples): q_t = trajectory.eval(t) # shape (7,) joint positions at time t # Timestamped trajectory (explicit waypoint times, cubic spline interpolation) times = [0.0, 1.0, 2.5, 4.0, 5.5] timed_traj = traj_gen.generate_time_stamped_trajectory( waypoints, times, cumotion.CSpaceTrajectoryGenerator.InterpolationMode.CUBIC_SPLINE ) print(f"Timed trajectory duration: {timed_traj.domain().span():.3f} s") # Tune solver parameters traj_gen.set_solver_param("max_segment_iterations", 10) traj_gen.set_solver_param("max_aggregate_iterations", 50) traj_gen.set_solver_param("convergence_dt", 0.001) ``` -------------------------------- ### Set cuMotion Log Level (Python) Source: https://context7.com/nvidia-isaac/cumotion/llms.txt This Python snippet shows how to set the verbosity of cuMotion's built-in logger. Use WARNING to suppress INFO and VERBOSE messages. ```python import cumotion cumotion.set_log_level(cumotion.LogLevel.WARNING) # WARNING (default) cumotion.set_log_level(cumotion.LogLevel.INFO) # show informational messages cumotion.set_log_level(cumotion.LogLevel.ERROR) # show errors only ``` -------------------------------- ### Set cuMotion Content Directory Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Determines and normalizes the absolute path to the cuMotion content directory, typically located relative to the cumotionConfig.cmake file. ```cmake if(NOT DEFINED CONTENT_DIR) # Find # content/ # relative to # lib/cmake/cumotion/cumotionConfig.cmake set(CONTENT_DIR "${cumotion_DIR}/../../../content") endif() cmake_path(ABSOLUTE_PATH CONTENT_DIR NORMALIZE) message(STATUS "cuMotion content directory: ${CONTENT_DIR}") ``` -------------------------------- ### Find Eigen3 Dependency Source: https://github.com/nvidia-isaac/cumotion/blob/main/examples/CMakeLists.txt Finds the Eigen3 library, which is a required dependency for the project. ```cmake find_package(Eigen3 REQUIRED) ``` -------------------------------- ### Generate Collision Spheres from Meshes Source: https://context7.com/nvidia-isaac/cumotion/llms.txt Use `create_collision_sphere_generator` to approximate a mesh with spheres for collision checking. The generated spheres can be saved in XRDF format. ```python import cumotion import numpy as np import open3d as o3d ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.