Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions example_scripts/cd_objective_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

ACTION_NAME = "/do_objective"
ACTION_TYPE = "moveit_studio_sdk_msgs/action/DoObjectiveSequence"
ACTION_STATUS_TOPIC = f"{ACTION_NAME}/_action/status"

TOTAL_TIMEOUT_S = 3600
POLL_INTERVAL_S = 10
Expand Down Expand Up @@ -108,29 +107,42 @@ def _connect_rosbridge(client: roslibpy.Ros, deadline: float) -> None:
_fail("Timeout: rosbridge websocket did not connect within 1h")


def _get_topics(client: roslibpy.Ros) -> list:
result = {"topics": None}
def _get_action_servers(client: roslibpy.Ros) -> list:
"""Query rosapi for the list of advertised action servers.

/rosapi/topics filters hidden topics (anything matching `_action/*`), so
enumerating via topics misses every ROS 2 action. /rosapi/action_servers
returns the action names directly.
"""
result = {"servers": []}
done = Event()

def _ok(resp):
result["topics"] = resp.get("topics", []) if isinstance(resp, dict) else []
# resp is roslibpy.ServiceResponse (dict-like but not a dict subclass)
# in current roslibpy; access via .get to stay compatible if that ever
# changes back to a plain dict.
result["servers"] = resp.get("action_servers", []) or []
done.set()

def _err(err):
print(f"rosapi topics call failed: {err}")
print(f"rosapi action_servers call failed: {err}")
done.set()

client.get_topics(_ok, _err)
service = roslibpy.Service(
client, "/rosapi/action_servers", "rosapi_msgs/srv/GetActionServers"
)
service.call(roslibpy.ServiceRequest(), callback=_ok, errback=_err)
if not done.wait(timeout=ROSAPI_CALL_TIMEOUT_S):
print("rosapi action_servers: timed out waiting for response", file=sys.stderr)
return []
return result["topics"] or []
return result["servers"]


def _wait_for_action_server(client: roslibpy.Ros, deadline: float) -> None:
attempt = 0
while time.monotonic() < deadline:
attempt += 1
if ACTION_STATUS_TOPIC in _get_topics(client):
if ACTION_NAME in _get_action_servers(client):
print(f"{ACTION_NAME} action server is up (attempt {attempt})")
return
print(f"Waiting for {ACTION_NAME} action server... (attempt {attempt})")
Expand Down
11 changes: 10 additions & 1 deletion install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ fi
if ! python3 -c "import roslibpy" 2>/dev/null; then
echo "Installing roslibpy"
sudo apt-get install -y python3-pip
python3 -m pip install --break-system-packages --ignore-installed roslibpy
# PEP 668: pip >= 23 on externally-managed Pythons (Ubuntu 23.04+,
# Debian 12+) refuses system-wide installs without --break-system-packages.
# Older pip (Ubuntu 22.04 ships 22.0.2) does not recognize the flag at all.
# Gate on the EXTERNALLY-MANAGED marker — present iff the flag is needed
# and supported.
PIP_ARGS=(--ignore-installed)
if compgen -G "/usr/lib/python3*/EXTERNALLY-MANAGED" > /dev/null; then
PIP_ARGS+=(--break-system-packages)
fi
python3 -m pip install "${PIP_ARGS[@]}" roslibpy
fi

echo "Installing CD objective shared library to /usr/lib/moveit-pro-scripts/"
Expand Down
Loading