The unified abstraction layer. Hosts the canonical multiprocessing
gym-proxy class and the ROS-side utility modules shared by every
package in the ecosystem.
Canonical gym-proxy implementation for the UniROS ecosystem.
This is the single source of truth for the multiprocessing
gym-proxy class used by multiros, realros, and uniros. Each of
those packages re-exports it under a historical name
(MultirosGym, RealrosGym, uniros_gym) so existing user
code continues to work — every alias points at the class defined
here, so a fix landed here automatically reaches all three
packages.
The proxy spawns a worker process that holds the actual gym.Env.
Parent-side method calls (step / reset / close /
attribute access) flow over a multiprocessing.Pipe to the worker
and back. Worker-side exceptions are caught and shipped back as
_RemoteException, so the parent re-raises with the
worker’s traceback instead of hanging on the next recv().
-
class uniros._proxy.GymProxy(env_name, *args, **kwargs)[source]
Bases: object
Parent-side proxy for a gym.Env running inside a worker process.
Equivalent aliases re-exported by other packages in the ecosystem:
All four names refer to the same class object.
Usage:
from uniros.core import uniros_gym as gym # or any alias
env = gym.make("env_name", **kwargs)
env.reset()
- Parameters:
-
-
static worker(env_name, conn, *args, **kwargs)[source]
- Parameters:
-
- Return type:
None
-
property unwrapped: GymProxy
Return self as the unwrapped env.
The proxy IS the user-visible env from the parent’s perspective;
whatever lives in the worker process is opaque and not accessible
across the pipe (gym.Env instances typically hold non-picklable
state such as _thread.RLock from rospy’s spinner threads, so
sending them through the pipe raises TypeError).
Without this handler, env.unwrapped would route through
__getattr__, IPC to the worker, and fail to pickle. SB3’s
DummyVecEnv calls id(env.unwrapped) for uniqueness checking
during construction, so this property is required for SB3
compatibility.
-
classmethod make(env_name, *args, **kwargs)[source]
- Parameters:
-
- Return type:
GymProxy
-
step(action)[source]
- Parameters:
action (Any)
- Return type:
Tuple[Any, float, bool, bool, Mapping[str, Any]]
-
reset(seed=None, options=None)[source]
- Parameters:
-
- Return type:
Tuple[Any, Mapping[str, Any]]
-
close()[source]
- Return type:
None
Re-export of the canonical gym proxy.
The implementation lives in uniros._proxy as
GymProxy. uniros_gym is a snake_case
alias kept for backwards compatibility — both names refer to the
same class object.
Usage:
from uniros.core import uniros_gym as gym
env = gym.make("env_name", args)
env.reset()
-
class uniros.core.GymProxy(env_name, *args, **kwargs)[source]
Bases: object
Parent-side proxy for a gym.Env running inside a worker process.
Equivalent aliases re-exported by other packages in the ecosystem:
All four names refer to the same class object.
Usage:
from uniros.core import uniros_gym as gym # or any alias
env = gym.make("env_name", **kwargs)
env.reset()
- Parameters:
-
-
static worker(env_name, conn, *args, **kwargs)[source]
- Parameters:
-
- Return type:
None
-
property unwrapped: GymProxy
Return self as the unwrapped env.
The proxy IS the user-visible env from the parent’s perspective;
whatever lives in the worker process is opaque and not accessible
across the pipe (gym.Env instances typically hold non-picklable
state such as _thread.RLock from rospy’s spinner threads, so
sending them through the pipe raises TypeError).
Without this handler, env.unwrapped would route through
__getattr__, IPC to the worker, and fail to pickle. SB3’s
DummyVecEnv calls id(env.unwrapped) for uniqueness checking
during construction, so this property is required for SB3
compatibility.
-
classmethod make(env_name, *args, **kwargs)[source]
- Parameters:
-
- Return type:
GymProxy
-
step(action)[source]
- Parameters:
action (Any)
- Return type:
Tuple[Any, float, bool, bool, Mapping[str, Any]]
-
reset(seed=None, options=None)[source]
- Parameters:
-
- Return type:
Tuple[Any, Mapping[str, Any]]
-
close()[source]
- Return type:
None
-
uniros.core.uniros_gym
alias of GymProxy
This script is to specify Classes for handling ROS markers.
- The RosMarker Class has the following methods,
01. set_frame_id: Set the frame ID of the marker.
02. set_ns: Set the namespace of the marker.
03. set_id: Set the ID of the marker.
04. set_type: Set the type of the marker.
05. set_action: Set the action of the marker.
06. set_pose: Set the pose of the marker.
07. set_position: Set the position of the marker.
08. set_orientation: Set the orientation of the marker.
09. set_duration: Set the lifetime of the marker.
10. set_scale: Set the scale of the marker.
11. set_color: Set the color of the marker.
12. publish: Publish the marker.
13. delete: Delete the marker.
14. update: Update the marker.
- The RosMarkerArray Class has the following methods,
01. add_marker: Add a new marker to the array.
02. remove_marker: Remove a marker from the array.
03. update_markers: Update all markers in the array.
04. publish: Publish all markers in the array.
05. delete_all_markers: Delete all markers in the array.
06. remove_all_markers: Remove all markers from the array.
07. get_marker_by_id: Get a marker by its ID.
08. get_markers_by_property: Get all markers with a specific property value.
-
class uniros.utils.ros_markers.RosMarker(frame_id, ns, marker_type, marker_topic, marker_id=0, action=visualization_msgs.msg.Marker.ADD, pose=None, position=None, orientation=None, lifetime=0.0, scale=None, color=None)[source]
Bases: object
A class for working with ROS markers.
This class provides methods for creating, updating, publishing and deleting a single ROS marker.
It allows you to set and change the marker properties such as position, orientation, scale, color and lifetime.
Initialize a RosMarker object.
- Parameters:
frame_id (str) – The frame ID of the marker.
ns (str) – The namespace of the marker.
marker_type (int) – The type of the marker.
marker_topic (str) – The topic to publish the marker to.
marker_id (int) – The ID of the marker (optional).
action (int) – The action of the marker (optional).
pose (list) – The pose of the marker [x, y, z, qx, qy, qz, qw] (optional).
position (Union[list, np.ndarray]) – The new position of the marker [x, y, z] (optional).
orientation (Union[list, np.ndarray]) – The new orientation of the marker [qx, qy, qz, qw] (optional).
lifetime (float) – The lifetime of the marker in seconds (optional).
scale (list) – The scale of the marker [x, y, z] (optional).
color (list) – The color of the marker [r, g, b, a] (optional).
- Marker types:
ARROW = 0
CUBE = 1
SPHERE = 2
CYLINDER = 3
LINE_STRIP = 4
LINE_LIST = 5
CUBE_LIST = 6
SPHERE_LIST = 7
POINTS = 8
TEXT_VIEW_FACING = 9
MESH_RESOURCE = 10
TRIANGLE_LIST = 11
-
set_frame_id(frame_id)[source]
Set the frame ID of the marker.
- Parameters:
frame_id (str) – The new frame ID of the marker.
- Return type:
None
-
set_ns(ns)[source]
Set the namespace of the marker.
- Parameters:
ns (str) – The new namespace of the marker.
- Return type:
None
-
set_id(marker_id)[source]
Set the ID of the marker.
- Parameters:
marker_id (int) – The new ID of the marker.
- Return type:
None
-
set_type(marker_type)[source]
Set the type of the marker.
- Parameters:
marker_type (int) – The new type of the marker.
- Return type:
None
-
set_action(action)[source]
Set the action of the marker.
- Parameters:
action (int) – The new action of the marker.
- Return type:
None
-
set_pose(pose)[source]
Set the pose of the marker.
- Parameters:
pose (list) – The new pose of the marker [x, y, z, qx, qy, qz, qw].
- Return type:
None
-
set_position(position)[source]
Set the position of the marker.
- Parameters:
position (Union[list, np.ndarray]) – The new position of the marker [x, y, z].
- Return type:
None
-
set_orientation(orientation)[source]
Set the orientation of the marker.
- Parameters:
orientation (Union[list, np.ndarray]) – The new orientation of the marker [qx, qy, qz, qw].
- Return type:
None
-
set_duration(duration)[source]
Set the lifetime of the marker.
- Parameters:
duration (float) – The new lifetime of the marker in seconds.
- Return type:
None
-
set_scale(scale)[source]
Set the scale of the marker.
- Parameters:
scale (list) – The new scale of the marker [x, y, z].
- Return type:
None
-
set_color(color=None, r=None, g=None, b=None, a=None)[source]
Set the color of the marker.
- Parameters:
color (list) – The new color of the marker [r, g, b, a] (optional).
r (float) – The new red component of the marker color (optional).
g (float) – The new green component of the marker color (optional).
b (float) – The new blue component of the marker color (optional).
a (float) – The new alpha component of the marker color (optional).
- Return type:
None
-
publish()[source]
Publish the marker.
- Return type:
None
-
delete()[source]
Delete the marker.
- Return type:
None
-
update(position=None, orientation=None, r=None, g=None, b=None, a=None, duration=None)[source]
Update the marker.
- Parameters:
position (Union[list, np.ndarray]) – The new position of the marker [x, y, z] (optional).
orientation (Union[list, np.ndarray]) – The new orientation of the marker [qx, qy, qz, qw] (optional).
r (float) – The new red component of the marker color (optional).
g (float) – The new green component of the marker color (optional).
b (float) – The new blue component of the marker color (optional).
a (float) – The new alpha component of the marker color (optional).
duration (float) – The new lifetime of the marker in seconds (optional).
- Return type:
None
-
class uniros.utils.ros_markers.RosMarkerArray(marker_topic)[source]
Bases: object
A class for working with arrays of ROS markers.
This class provides methods for managing a list of RosMarker instances and publishing them as a MarkerArray.
It allows you to add, remove, update and delete multiple markers at once.
Initialize the RosMarkerArray.
- Parameters:
marker_topic (str) – The topic to publish the markers on.
-
add_marker(frame_id, ns, marker_type, marker_topic='', marker_id=0, action=visualization_msgs.msg.Marker.ADD, pose=None, position=None, orientation=None, lifetime=0.0, scale=None, color=None)[source]
Add a new marker to the array.
- Parameters:
frame_id (str) – The frame ID of the marker.
ns (str) – The namespace of the marker.
marker_type (int) – The type of the marker.
marker_topic (str) – The topic to publish the marker to (optional).
marker_id (int) – The ID of the marker (optional).
action (int) – The action of the marker (optional).
pose (list) – The pose of the marker [x, y, z, qx, qy, qz, qw] (optional).
position (Union[list, np.ndarray]) – The new position of the marker [x, y, z] (optional).
orientation (Union[list, np.ndarray]) – The new orientation of the marker [qx, qy, qz, qw] (optional).
lifetime (float) – The lifetime of the marker in seconds (optional).
scale (list) – The scale of the marker [x, y, z] (optional).
color (list) – The color of the marker [r, g, b, a] (optional).
- Return type:
None
-
remove_marker(marker_id)[source]
Remove a marker from the array.
- Parameters:
marker_id (int) – The ID of the marker to remove.
- Return type:
None
-
update_markers(frame_id=None, ns=None, marker_type=None, action=None, position=None, orientation=None, scale=None, color=None, lifetime=None)[source]
Update all markers in the array.
- Parameters:
frame_id (str) – The new frame ID of the markers (optional)
ns (str) – The new namespace of the markers (optional).
marker_type (int) – The new type of the markers (optional).
action (int) – The new action of the markers (optional).
position (list) – The new position of the markers [x, y, z] (optional).
orientation (list) – The new orientation of the markers [qx, qy, qz, qw] (optional).
scale (list) – The new scale of the markers [x, y, z] (optional).
color (list) – The new color of the markers [r, g, b, a] (optional).
lifetime (float) – The new lifetime of the markers in seconds (optional).
- Return type:
None
-
publish()[source]
Publish all markers in the array.
- Return type:
None
-
delete_all_markers()[source]
Delete all markers in the array.
- Return type:
None
-
remove_all_markers()[source]
Remove all markers from the array.
- Return type:
None
-
get_marker_by_id(marker_id)[source]
Get a marker by its ID.
- Parameters:
marker_id (int) – The ID of the marker to get.
- Returns:
The marker with the specified ID, or None if no such marker exists.
- Return type:
RosMarker
-
get_markers_by_property(property_name, property_value)[source]
Get all markers with a specific property value.
- Parameters:
property_name (str) – The name of the property to check (e.g., “ns” or “type”).
property_value (Any) – The value of the property to check for.
- Returns:
A list of all markers with the specified property value.
- Return type:
list[RosMarker]
There are two classes in this file that provide similar functionality:
- Kinematics_pyrobot: This is modified from the Kinematics class in the pyrobot repo.
- Kinematics_pykdl: Kinematics class based on pykdl_utils package.
These classes provide kinematics functionality for a robot. Instead of using computation-heavy ROS packages like MoveIt,
this class uses the KDL library to perform kinematics calculations.
With these classes, you can calculate,
- Forward kinematics - compute the pose of the end-effector given the joint angles
- Inverse kinematics - compute the joint angles given the pose of the end-effector
Since both classes provide similar functionality, you can use either one of them. However, the Kinematics_pyrobot class
is recommended since it is more flexible and provides more functionality.
-
class uniros.utils.ros_kinematics.Kinematics_pyrobot(robot_description_parm, base_link, end_link, debug=False)[source]
Bases: object
This is modified from the Kinematics class in the pyrobot repo.
link: https://github.com/facebookresearch/pyrobot/blob/b334b60842271d9d8f4ed7a97bc4e5efe8bb72d6/pyrobot_bridge/nodes/kinematics.py
Initialize the Kinematics class.
- Parameters:
robot_description_parm (str) – robot description parameter name including the namespace
base_link (str) – base link of the robot including the namespace
end_link (str) – end-effector link of the robot including the namespace
debug (bool) – debug flag
-
calculate_ik(target_pose, tolerance, init_joint_positions)[source]
Calculate the inverse kinematics for a given pose.
- Parameters:
target_pose (list) – The desired position and orientation of the end effector given as [x, y, z, qx, qy, qz, qw]
tolerance (list) – The tolerance for each of the pose components
init_joint_positions (list) – The initial positions of the joints from which to start the IK calculation
- Returns:
A tuple (success, joint_positions), where success is a boolean indicating success of IK,
and joint_positions are the calculated joint angles.
- Return type:
Tuple[bool, ndarray | None]
-
static rot_mat_to_quat(rot)[source]
Convert the rotation matrix into quaternion.
- Parameters:
rot (numpy.ndarray) – the rotation matrix (shape: \([3, 3]\))
- Returns:
\([4,]\))
- Return type:
quaternion (numpy.ndarray) [x, y, z, w] (shape
-
static joints_to_kdl(joint_values)[source]
Convert the numpy array into KDL data format
- Parameters:
joint_values – values for the joints
- Returns:
kdl data type for the joints
-
calculate_fk(joint_positions, des_frame, euler=True)[source]
Given joint angles, compute the pose of desired_frame with respect
to the base frame. The desired frame must be in self.arm_link_names.
- Parameters:
joint_positions (np.ndarray) – Joint angles.
des_frame (str) – Desired frame.
euler (bool) – If True, return the orientation in Euler angles.
- Returns:
A tuple (success, pos, rpy), where success is a boolean indicating success of FK,
and pos are the calculated position and rpy are the calculated roll, pitch, yaw.
- Return type:
Tuple[bool, ndarray | None]
-
class uniros.utils.ros_kinematics.Kinematics_pykdl(robot_description_parm, base_link, end_link, debug=False)[source]
Bases: object
Kinematics class based on pykdl_utils package.
https://github.com/ncbdrck/hrl-kdl
Initialize the Kinematics class.
- Parameters:
robot_description_parm (str) – robot description parameter name including the namespace
base_link (str) – base link of the robot including the namespace
end_link (str) – end-effector link of the robot including the namespace
debug (bool) – debug mode
-
static rot_mat_to_quat(rot)[source]
Convert the rotation matrix into quaternion.
- Parameters:
rot (numpy.ndarray) – the rotation matrix (shape: \([3, 3]\))
- Returns:
\([4,]\))
- Return type:
quaternion (numpy.ndarray) [x, y, z, w] (shape
-
calculate_fk(joint_positions, end_link=None, base_link=None, euler=True)[source]
Given joint angles, compute the pose of desired_frame with respect
to the base frame. The desired frame must be in self.arm_link_names.
- Parameters:
joint_positions (np.ndarray) – Joint angles.
end_link (str) – Desired frame. If None, the end-effector frame is used.
base_link (str) – Base frame. If None, the base frame is used.
euler (bool) – If True, return the orientation in Euler angles.
- Returns:
A tuple (success, pos, rpy), where success is a boolean indicating success of FK,
and pos are the calculated position and rpy are the calculated roll, pitch, yaw.
- Return type:
Tuple[bool, ndarray | None]
-
calculate_ik(target_pose, init_joint_positions=None)[source]
Calculate the inverse kinematics for a given pose.
- Parameters:
target_pose (matrix) – The desired position and orientation of the end effector given as a 4x4 matrix
init_joint_positions (list) – The initial positions of the joints from which to start the IK calculation
- Returns:
A tuple (success, joint_positions), where success is a boolean indicating success of IK,
and joint_positions are the calculated joint angles.
- Return type:
Tuple[bool, ndarray | None]
Functions for handling ROS controllers via the controller_manager
services.
Functions provided:
load_ros_controller — load a ROS controller.
load_controller_list — load a list of controllers.
list_loaded_controllers — list all loaded controllers.
unload_ros_controller — unload a controller.
unload_controller_list — unload a list of controllers.
switch_controllers — switch between two sets of controllers.
start_controllers — start a list of controllers.
stop_controllers — stop a list of controllers.
reset_controllers — stop then re-start a list of controllers.
spawn_controllers — load then start a list of controllers.
unspawn_controllers — stop then unload a list of controllers.
Every helper wraps its underlying service call with a 30-second
rospy.wait_for_service timeout so a hung controller_manager
surfaces as a logged failure rather than an indefinite hang.
ROS service reference:
http://docs.ros.org/en/noetic/api/controller_manager_msgs/html/index-msg.html
-
uniros.utils.ros_controllers.load_ros_controller(controller_name, ns=None, max_retries=5)[source]
Function to load a ROS controller using the controller_manager_msgs/LoadController service.
(Need to have this controller loaded in the parameter server)
- Parameters:
controller_name (str) – The name of the controller to load.
ns (str) – The namespace of the controller_manager service (optional).
max_retries (int) – The maximum number of times to retry loading the controller (optional).
- Returns:
True if the controller was successfully loaded, False otherwise.
- Return type:
bool
-
uniros.utils.ros_controllers.load_controller_list(controller_list, ns=None, max_retries=5)[source]
Function to load a list of ROS controllers.
- Parameters:
controller_list (list) – A list of controller names to load.
ns (str) – The namespace of the controller_manager service (optional).
max_retries (int) – The maximum number of times to retry loading each controller (optional).
- Returns:
True if all controllers were successfully loaded, False otherwise.
- Return type:
bool
-
uniros.utils.ros_controllers.list_loaded_controllers(ns=None, max_retries=5)[source]
Function to list all loaded ROS controllers using the controller_manager_msgs/ListControllers service.
- Parameters:
-
- Returns:
- A list of loaded controller names. If an error occurred while calling the service,
an empty list is returned.
- Return type:
list
-
uniros.utils.ros_controllers.unload_ros_controller(controller_name, ns=None, max_retries=5)[source]
Function to unload a ROS controller using the controller_manager_msgs/UnloadController service.
- Parameters:
controller_name (str) – The name of the controller to unload.
ns (str) – The namespace of the controller_manager service (optional).
max_retries (int) – The maximum number of times to retry unloading the controller (optional).
- Returns:
True if the controller was successfully unloaded, False otherwise.
- Return type:
bool
-
uniros.utils.ros_controllers.unload_controller_list(controller_list, ns=None, max_retries=5)[source]
Function to unload a list of ROS controllers using the unload_ros_controller function.
- Parameters:
controller_list (list) – A list of controller names to unload.
ns (str) – The namespace of the controller_manager service (optional).
max_retries (int) – The maximum number of times to retry unloading each controller (optional).
- Returns:
True if all controllers were successfully unloaded, False otherwise.
- Return type:
bool
-
uniros.utils.ros_controllers.switch_controllers(start_controllers_list, stop_controllers_list, ns=None, strictness=1, start_asap=False, timeout=0.0, max_retries=5)[source]
Function to switch between two sets of ROS controllers using the controller_manager_msgs/SwitchController service.
- Parameters:
start_controllers_list (list) – A list of controller names to start.
stop_controllers_list (list) – A list of controller names to stop.
ns (str) – The namespace of the controller_manager service (optional).
strictness (int) – The level of strictness to use when switching controllers (optional).
1 = BEST_EFFORT, 2 = STRICT.
start_asap (bool) – Whether to start controllers in the start_controllers list as soon as possible (optional).
timeout (float) – The maximum amount of time to wait for the controller switch to complete (optional).
max_retries (int) – The maximum number of times to retry switching controllers (optional).
- Returns:
True if the controllers were successfully switched, False otherwise.
- Return type:
bool
-
uniros.utils.ros_controllers.start_controllers(controller_list, ns=None, strictness=1, start_asap=False, timeout=0.0, max_retries=5)[source]
Function to start a list of ROS controllers using the switch_controllers function.
- Parameters:
controller_list (list) – A list of controller names to start.
ns (str) – The namespace of the controller_manager service (optional).
strictness (int) – The level of strictness to use when starting controllers (optional).
1 = BEST_EFFORT, 2 = STRICT.
start_asap (bool) – Whether to start controllers in the controller_list as soon as possible (optional).
timeout (float) – The maximum amount of time to wait for the controllers to start (optional).
max_retries (int) – The maximum number of times to retry starting controllers (optional).
- Returns:
True if all controllers were successfully started, False otherwise.
- Return type:
bool
-
uniros.utils.ros_controllers.stop_controllers(controller_list, ns=None, strictness=1, start_asap=False, timeout=0.0, max_retries=5)[source]
Function to stop a list of ROS controllers using the switch_controllers function.
- Parameters:
controller_list (list) – A list of controller names to stop.
ns (str) – The namespace of the controller_manager service (optional).
strictness (int) – The level of strictness to use when stopping controllers (optional).
1 = BEST_EFFORT, 2 = STRICT.
start_asap (bool) – Whether to stop controllers in the controller_list as soon as possible (optional).
timeout (float) – The maximum amount of time to wait for the controllers to stop (optional).
max_retries (int) – The maximum number of times to retry stopping controllers (optional).
- Returns:
True if all controllers were successfully stopped, False otherwise.
- Return type:
bool
-
uniros.utils.ros_controllers.reset_controllers(controller_list, ns=None, strictness=1, start_asap=False, timeout=0.0, max_retries=5)[source]
Function to “reset” a list of ROS controllers by stopping and then starting them again.
- Parameters:
controller_list (list) – A list of controller names to reset.
ns (str) – The namespace of the controller_manager service (optional).
strictness (int) – The level of strictness to use when resetting controllers (optional).
1 = BEST_EFFORT, 2 = STRICT.
start_asap (bool) – Whether to start controllers in the controller_list as soon as possible (optional).
timeout (float) – The maximum amount of time to wait for the controllers to reset (optional).
max_retries (int) – The maximum number of times to retry resetting controllers (optional).
- Returns:
True if all controllers were successfully reset, False otherwise.
- Return type:
bool
-
uniros.utils.ros_controllers.spawn_controllers(controller_list, ns=None, strictness=1, start_asap=False, timeout=0.0, max_retries=5)[source]
Function to spawn a list of ROS controllers by loading and then starting them.
- Parameters:
controller_list (list) – A list of controller names to spawn.
ns (str) – The namespace of the controller_manager service (optional).
strictness (int) – The level of strictness to use when spawning controllers (optional).
1 = BEST_EFFORT, 2 = STRICT.
start_asap (bool) – Whether to start controllers in the controller_list as soon as possible (optional).
timeout (float) – The maximum amount of time to wait for the controllers to spawn (optional).
max_retries (int) – The maximum number of times to retry spawning controllers (optional).
- Returns:
True if all controllers were successfully spawned, False otherwise.
- Return type:
bool
-
uniros.utils.ros_controllers.unspawn_controllers(controller_list, ns=None, strictness=1, start_asap=False, timeout=0.0, max_retries=5)[source]
Function to unspawn a list of ROS controllers by stopping and then unloading them.
- Parameters:
controller_list (list) – A list of controller names to unspawn.
ns (str) – The namespace of the controller_manager service (optional).
strictness (int) – The level of strictness to use when unspawning controllers (optional).
1 = BEST_EFFORT, 2 = STRICT.
start_asap (bool) – Whether to stop controllers in the controller_list as soon as possible (optional).
timeout (float) – The maximum amount of time to wait for the controllers to unspawn (optional).
max_retries (int) – The maximum number of times to retry unspawning controllers (optional).
- Returns:
True if all controllers were successfully unspawned, False otherwise.
- Return type:
bool