Isaac Sim Version
4.5.0
4.2.0
4.1.0
4.0.0
4.5.0
2023.1.1
2023.1.0-hotfix.1
Other (please specify):
Operating System
Ubuntu 22.04
Ubuntu 20.04
Windows 11
Windows 10
Other (please specify):
GPU Information
- Model: NVIDIA RTX 3500 Ada Generation
- Driver Version: 565.57.01
Topic Description
I am trying to drive a Locobot in Isaac Sim using Python code. The robot file is an URDF.
I tried to do it by creating an action graph via Python, but nothing worked when sending the velocity command via the ros topic. I have checked the connections, the joint, etc., multiple times.
After a bit of research, I guessed that from Python code, the robot should be controlled via Wheeled Robots [omni.isaac.wheeled_robots].
The robot also has an arm, but I only focus on his Kobuki base. I followed the documentation for the Wheeled robot and also checked the URDF documentation . However, I am still unable to move the robot. But I noticed that when the simulation is loaded, and I send velocity command via the ros topic, surprisingly, the robot arm moves while I am using âapply_wheel_actions.â
Code functions
The functions responsible of the robot import and the motion
def _load_robot(self):
try:
import_config = _urdf.ImportConfig()
import_config.merge_fixed_joints = True
import_config.fix_base = False
import_config.self_collision = True
import_config.create_physics_scene = True
status, prim_path = omni.kit.commands.execute(
'URDFParseAndImportFile',
urdf_path=self.urdf_path,
import_config=import_config
)
if not status:
raise RuntimeError("URDF import failed")
stage = omni.usd.get_context().get_stage()
if not stage.GetPrimAtPath(prim_path):
raise RuntimeError(f"Invalid prim path: {prim_path}")
self.robot_path = prim_path
simulation_app.update()
self.wheeled_robot = WheeledRobot(
prim_path=self.robot_path,
name="locobot_base",
wheel_dof_names=["wheel_left_joint", "wheel_right_joint"]
)
self.world.scene.add(self.wheeled_robot)
self.wheeled_robot.initialize()
self._configure_wheels()
self._setup_velocity_control()
simulation_app.update()
except Exception as e:
raise RuntimeError(f"Robot loading failed: {str(e)}")
def _configure_wheels(self):
if hasattr(self.wheeled_robot, '_articulation_view'):
dof_props = self.wheeled_robot.dof_properties
wheel_indices = [
self.wheeled_robot.get_dof_index("wheel_left_joint"),
self.wheeled_robot.get_dof_index("wheel_right_joint")
]
for idx in wheel_indices:
dof_props[idx]['driveMode'] = 1
dof_props[idx]['stiffness'] = 0.0
dof_props[idx]['damping'] = self.wheel_params["damping"]
dof_props[idx]['maxEffort'] = self.wheel_params["max_effort"]
self.get_logger().info(f"Wheels configured: indices={wheel_indices}")
def _setup_velocity_control(self):
self.create_subscription(Twist, '/cmd_vel', self._on_cmd_vel, 10)
def _on_cmd_vel(self, msg):
try:
if not hasattr(self, 'wheeled_robot'): return
# Convert m/s to stage units
linear_vel = msg.linear.x * 100 # Scale up for better response
angular_vel = msg.angular.z
# Calculate wheel velocities (rad/s)
left_wheel = (linear_vel - angular_vel * self.wheel_params["wheel_distance"]) / self.wheel_params["wheel_radius"]
right_wheel = (linear_vel + angular_vel * self.wheel_params["wheel_distance"]) / self.wheel_params["wheel_radius"]
drive = ArticulationAction()
drive.joint_velocities = np.array([left_wheel, right_wheel])
self.wheeled_robot.apply_wheel_actions(drive)
self.world.step(render=True)
simulation_app.update()
except Exception as e:
self.get_logger().error(f"Velocity command failed: {str(e)}")
Screenshots or Videos
Additional Information
The robot wheels parameters
self.wheel_params = {
"wheel_radius": 0.033,
"wheel_distance": 0.23,
"max_linear_speed": 2.0,
"max_angular_speed": 4.0,
"max_wheel_speed": 10.0,
"damping": 500.0,
"max_effort": 5000.0