Skip to content

Commit be8a5a2

Browse files
Jelmerdwgeurto
authored andcommitted
435 integrate meta (#437)
* Add Meta platform to our system. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * First teleoperation. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Rewrite teleoperation python node to CPP meta manager node. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Use meta as flag, not as platform. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Add support for GUI debugging using dev container. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Tune servo params. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Switch to meta_quest_reader package. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Switch to ppadb-reborn that includes fixes for escape sequences. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Add scrcpy to stream quest. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Start other containers only when meta launches correctly. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Fix linting. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Fix configuration, to support Meta, Joystick and GUI. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Set servo command type from joystick manager and meta manager. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Add documentation. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Undo scale changes in servo params. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> * Apply feedback. Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> --------- Signed-off-by: Jelmer de Wolde <jelmer.de.wolde@alliander.com> Signed-off-by: Peter Geurts <peter.geurts@proton.me>
1 parent 8d89332 commit be8a5a2

34 files changed

Lines changed: 2236 additions & 378 deletions

File tree

.devcontainer/dev/Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ RUN git clone --depth=1 --filter=blob:none -b v3.1.1 \
4343
&& cd src/franka_ros2 \
4444
&& git sparse-checkout set franka_msgs
4545

46+
# Install debug tools:
47+
RUN apt update && apt install -y --no-install-recommends \
48+
ros-$ROS_DISTRO-plotjuggler-ros \
49+
ros-$ROS_DISTRO-rqt-tf-tree
50+
4651
# Setup configuration files:
4752
COPY .devcontainer/dev/.dev_bashrc /.dev_bashrc
4853
RUN echo "source /.dev_bashrc" >> /home/$REMOTE_USER/.bashrc
@@ -52,6 +57,7 @@ COPY alliander_core/src/ /alliander/ros/src
5257
COPY alliander_diagnostics/src/ /alliander/ros/src
5358
COPY alliander_franka/src/ /alliander/ros/src
5459
COPY alliander_joystick/src/ /alliander/ros/src
60+
COPY alliander_meta/src/ /alliander/ros/src
5561
COPY alliander_moveit/src/ /alliander/ros/src
5662
COPY alliander_nav2/src/ /alliander/ros/src
5763
COPY alliander_xsens/src/ /alliander/ros/src

.devcontainer/dev/devcontainer.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,21 @@
1414
"workspaceMount": "source=${localWorkspaceFolder},target=/alliander_robotics,type=bind",
1515
"workspaceFolder": "/alliander_robotics",
1616
"overrideCommand": true,
17+
"mounts": [
18+
"source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind,consistency=cached"
19+
],
1720
"runArgs": [
18-
"--rm"
21+
"--rm",
22+
"--privileged",
23+
"--network=host",
24+
"-e",
25+
"DISPLAY",
26+
"-e",
27+
"NVIDIA_VISIBLE_DEVICES=all",
28+
"-e",
29+
"NVIDIA_DRIVER_CAPABILITIES=all",
30+
"-e",
31+
"RMW_IMPLEMENTATION=rmw_cyclonedds_cpp"
1932
],
2033
"customizations": {
2134
"vscode": {

alliander_core/src/alliander_description/franka/urdf/franka.urdf.xacro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0
1111
<xacro:arg name="xyz_ee" default="0 0 0" />
1212
<xacro:arg name="rpy_ee" default="0 0 ${-pi/4}" />
1313
<xacro:arg name="tcp_xyz" default="0 0 0.1034" />
14-
<xacro:arg name="tcp_rpy" default="0 0 0" />
14+
<xacro:arg name="tcp_rpy" default="3.1415 0 0" />
1515

1616
<!-- Custom arguments: -->
1717
<xacro:arg name="namespace" default="" />

alliander_joystick/alliander_joystick.Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ FROM $BASE_IMAGE
77
ARG COLCON_BUILD_SEQUENTIAL
88
ENV ROS_DISTRO=jazzy
99

10+
# Install ROS depenencies:
11+
RUN apt update && apt install -y ros-$ROS_DISTRO-moveit-msgs
12+
1013
# Install repo packages:
1114
WORKDIR /$WORKDIR/ros
1215
COPY alliander_core/src/ /$WORKDIR/ros/src

alliander_joystick/src/alliander_joystick/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ find_package(rclcpp REQUIRED)
1313
find_package(rclcpp_action REQUIRED)
1414
find_package(geometry_msgs REQUIRED)
1515
find_package(sensor_msgs REQUIRED)
16+
find_package(moveit_msgs REQUIRED)
1617
find_package(std_srvs REQUIRED)
1718
find_package(alliander_interfaces REQUIRED)
1819

1920
# C++ executables:
2021
include_directories(include)
21-
add_executable(joystick_manager
22+
add_executable(joystick_manager
2223
src/main.cpp
2324
src/joystick_manager.cpp
2425
)
@@ -30,6 +31,7 @@ ament_target_dependencies(joystick_manager
3031
rclcpp_action
3132
geometry_msgs
3233
sensor_msgs
34+
moveit_msgs
3335
std_srvs
3436
alliander_interfaces
3537
)

alliander_joystick/src/alliander_joystick/include/joystick_manager.hpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <alliander_interfaces/srv/string_srv.hpp>
1010
#include <cstdint>
1111
#include <geometry_msgs/msg/twist_stamped.hpp>
12+
#include <moveit_msgs/srv/servo_command_type.hpp>
1213
#include <rclcpp/client.hpp>
1314
#include <rclcpp/node.hpp>
1415
#include <rclcpp/node_options.hpp>
@@ -22,6 +23,7 @@
2223
using std::placeholders::_1;
2324
using std::placeholders::_2;
2425
typedef alliander_interfaces::action::TriggerAction TriggerAction;
26+
typedef moveit_msgs::srv::ServoCommandType ServoCommandType;
2527

2628
enum Button {
2729
A = 0, // Switch between platform modes
@@ -62,28 +64,19 @@ class JoystickManager {
6264
/// Client to move the arm back to home position
6365
rclcpp::Client<alliander_interfaces::srv::StringSrv>::SharedPtr
6466
srv_client_arm_home;
67+
/// Client to change the command type of the servo node
68+
rclcpp::Client<ServoCommandType>::SharedPtr
69+
srv_client_switch_servo_command_type;
6570
/// Client to trigger the arm's gripper to open
6671
rclcpp_action::Client<TriggerAction>::SharedPtr action_client_gripper_open;
6772
/// Client to trigger the arm's gripper to close
6873
rclcpp_action::Client<TriggerAction>::SharedPtr action_client_gripper_close;
6974

7075
// ROS2 get parameter variables:
71-
/// The arm twist topic
72-
std::string arm_topic;
73-
/// Frame ID of the arm
74-
std::string arm_frame_id;
75-
/// Name of the arm's gripper
76-
std::string arm_gripper_name;
77-
/// Service name with which the arm can be moved back to its home position
78-
std::string arm_home_service;
79-
/// Service name with which the arm's servo node can be paused
80-
std::string arm_pause_servo_service;
81-
/// The vehicle twist topic
82-
std::string vehicle_topic;
83-
/// Service name for resetting the vehicle's E-stop
84-
std::string vehicle_estop_reset_service;
85-
/// Service name for triggering the vehicle's E-stop
86-
std::string vehicle_estop_trigger_service;
76+
/// The namespace of the arm
77+
std::string namespace_arm;
78+
/// The namespace of the vehicle
79+
std::string namespace_vehicle;
8780

8881
// Other variables:
8982
/// Previous input values of the Joy message
@@ -182,6 +175,11 @@ class JoystickManager {
182175
*/
183176
void move_arm_to_home();
184177

178+
/**
179+
* @brief Call the service to switch the command type of the servo node
180+
*/
181+
void switch_servo_command_type();
182+
185183
/**
186184
* @brief (un)pause the servo node via a service request.
187185
* @param pause indication whether the servo node should be paused (true) or

alliander_joystick/src/alliander_joystick/launch/joystick.launch.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ def launch_setup(context: LaunchContext) -> list:
2929
platforms = PlatformList.from_str(platform_list_arg.string_value(context)).platforms
3030

3131
# Create default namespaces which can be ignored when left unchanged
32-
arm_namespace = "/arm"
33-
vehicle_namespace = "/vehicle"
32+
arm_namespace = "arm"
33+
vehicle_namespace = "vehicle"
3434

3535
# Find arm / vehicle platforms in the platform list
3636
for platform in platforms:
3737
match platform.platform_type:
3838
case "Arm":
39-
if arm_namespace == "/arm":
40-
arm_namespace = f"/{platform.namespace}"
39+
if arm_namespace == "arm":
40+
arm_namespace = platform.namespace
4141
else:
4242
warnings.warn(
4343
"No support for multiple arms yet, only accepting the first arm.",
@@ -46,8 +46,8 @@ def launch_setup(context: LaunchContext) -> list:
4646
)
4747

4848
case "Vehicle":
49-
if vehicle_namespace == "/vehicle":
50-
vehicle_namespace = f"/{platform.namespace}"
49+
if vehicle_namespace == "vehicle":
50+
vehicle_namespace = platform.namespace
5151
else:
5252
warnings.warn(
5353
"No support for multiple vehicles yet, only accepting the first vehicle.",
@@ -58,7 +58,7 @@ def launch_setup(context: LaunchContext) -> list:
5858
case _:
5959
pass
6060

61-
if arm_namespace == "/arm" and vehicle_namespace == "/vehicle":
61+
if arm_namespace == "arm" and vehicle_namespace == "vehicle":
6262
raise RuntimeError(
6363
"No arm/vehicle platform present, cancelling the joystick manager."
6464
)
@@ -68,16 +68,8 @@ def launch_setup(context: LaunchContext) -> list:
6868
executable="joystick_manager",
6969
name="joystick_manager",
7070
parameters=[
71-
{"arm_cmd_topic": f"{arm_namespace}/servo_node/delta_twist_cmds"},
72-
{"arm_frame_id": f"{arm_namespace[1:]}/fr3_link1"},
73-
{"arm_gripper_name": f"{arm_namespace}/gripper"},
74-
{
75-
"arm_home_service": f"{arm_namespace}/moveit_manager/move_to_configuration"
76-
},
77-
{"arm_pause_servo_service": f"{arm_namespace}/servo_node/pause_servo"},
78-
{"vehicle_cmd_topic": f"{vehicle_namespace}/cmd_vel_joy"},
79-
{"vehicle_estop_reset": f"{vehicle_namespace}/hardware/e_stop_reset"},
80-
{"vehicle_estop_trigger": f"{vehicle_namespace}/hardware/e_stop_trigger"},
71+
{"namespace_arm": arm_namespace},
72+
{"namespace_vehicle": vehicle_namespace},
8173
],
8274
)
8375

alliander_joystick/src/alliander_joystick/src/joystick_manager.cpp

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,8 @@
55
#include "joystick_manager.hpp"
66

77
JoystickManager::JoystickManager(rclcpp::Node::SharedPtr node) : node(node) {
8-
arm_topic = node->get_parameter("arm_cmd_topic").as_string();
9-
arm_frame_id = node->get_parameter("arm_frame_id").as_string();
10-
arm_gripper_name = node->get_parameter("arm_gripper_name").as_string();
11-
arm_home_service = node->get_parameter("arm_home_service").as_string();
12-
arm_pause_servo_service =
13-
node->get_parameter("arm_pause_servo_service").as_string();
14-
vehicle_topic = node->get_parameter("vehicle_cmd_topic").as_string();
15-
vehicle_estop_reset_service =
16-
node->get_parameter("vehicle_estop_reset").as_string();
17-
vehicle_estop_trigger_service =
18-
node->get_parameter("vehicle_estop_trigger").as_string();
8+
namespace_arm = node->get_parameter("namespace_arm").as_string();
9+
namespace_vehicle = node->get_parameter("namespace_vehicle").as_string();
1910

2011
initialize_joystick_manager();
2112

@@ -36,27 +27,29 @@ void JoystickManager::initialize_joystick_manager() {
3627
std::bind(&JoystickManager::joy_cb, this, _1));
3728

3829
// Publishers
39-
pub_arm_vel =
40-
node->create_publisher<geometry_msgs::msg::TwistStamped>(arm_topic, 10);
30+
pub_arm_vel = node->create_publisher<geometry_msgs::msg::TwistStamped>(
31+
"/" + namespace_arm + "/servo_node/delta_twist_cmds", 10);
4132
pub_vehicle_vel = node->create_publisher<geometry_msgs::msg::TwistStamped>(
42-
vehicle_topic, 10);
33+
"/" + namespace_vehicle + "/cmd_vel_joy", 10);
4334

4435
// Service clients
4536
srv_client_estop_trigger = node->create_client<std_srvs::srv::Trigger>(
46-
vehicle_estop_trigger_service);
47-
srv_client_estop_reset =
48-
node->create_client<std_srvs::srv::Trigger>(vehicle_estop_reset_service);
49-
srv_client_pause_servo =
50-
node->create_client<std_srvs::srv::SetBool>(arm_pause_servo_service);
37+
"/" + namespace_vehicle + "/hardware/e_stop_trigger");
38+
srv_client_estop_reset = node->create_client<std_srvs::srv::Trigger>(
39+
"/" + namespace_vehicle + "/hardware/e_stop_reset");
40+
srv_client_pause_servo = node->create_client<std_srvs::srv::SetBool>(
41+
"/" + namespace_arm + "/servo_node/pause_servo");
5142
srv_client_arm_home =
5243
node->create_client<alliander_interfaces::srv::StringSrv>(
53-
arm_home_service);
44+
"/" + namespace_arm + "/moveit_manager/move_to_configuration");
45+
srv_client_switch_servo_command_type = node->create_client<ServoCommandType>(
46+
"/" + namespace_arm + "/servo_node/switch_command_type");
5447

5548
// Action clients
5649
action_client_gripper_open = rclcpp_action::create_client<TriggerAction>(
57-
node, arm_gripper_name + "/open");
50+
node, "/" + namespace_arm + "/open");
5851
action_client_gripper_close = rclcpp_action::create_client<TriggerAction>(
59-
node, arm_gripper_name + "/close");
52+
node, "/" + namespace_arm + "/close");
6053

6154
// Log initial mode
6255
switch (current_mode) {
@@ -125,11 +118,13 @@ void JoystickManager::handle_button_input(const std::vector<int32_t>& buttons) {
125118
return;
126119
case vehicle_mode:
127120
RCLCPP_INFO(node->get_logger(), "Switch to ARM mode.");
121+
switch_servo_command_type();
128122
current_mode = arm_mode;
129123
pub_vehicle_vel->publish(geometry_msgs::msg::TwistStamped{});
130124
return;
131125
case no_mode:
132126
RCLCPP_INFO(node->get_logger(), "Switch to ARM mode.");
127+
switch_servo_command_type();
133128
current_mode = arm_mode;
134129
return;
135130
default:
@@ -222,7 +217,7 @@ void JoystickManager::handle_arm_movement(const float& x, const float& y,
222217
const float& rotation) {
223218
geometry_msgs::msg::TwistStamped twist;
224219
twist.header.stamp = node->now();
225-
twist.header.frame_id = arm_frame_id;
220+
twist.header.frame_id = namespace_arm + "/" + "fr3_link1";
226221

227222
twist.twist.linear.x = (std::abs(x) > dead_axis_zone)
228223
? (x * arm_speed_scale)
@@ -283,6 +278,35 @@ void JoystickManager::move_arm_to_home() {
283278
});
284279
}
285280

281+
// Switch the servo command type to TWIST:
282+
void JoystickManager::switch_servo_command_type() {
283+
auto request = std::make_shared<ServoCommandType::Request>();
284+
request->command_type = 1;
285+
286+
if (!srv_client_switch_servo_command_type->service_is_ready()) {
287+
RCLCPP_WARN(node->get_logger(),
288+
"'Switch servo command type' service not available.");
289+
}
290+
291+
srv_client_switch_servo_command_type->async_send_request(
292+
request, [this](rclcpp::Client<ServoCommandType>::SharedFuture future) {
293+
try {
294+
auto response = future.get();
295+
296+
if (response->success) {
297+
RCLCPP_INFO(node->get_logger(), "Servo command type is TWIST.");
298+
} else {
299+
RCLCPP_WARN(node->get_logger(),
300+
"Failed to set servo command type.");
301+
}
302+
} catch (const std::exception& e) {
303+
RCLCPP_ERROR(node->get_logger(),
304+
"'Switch servo command type' service call failed: %s",
305+
e.what());
306+
}
307+
});
308+
}
309+
286310
void JoystickManager::pause_servo_node(bool pause) {
287311
auto request = std::make_shared<std_srvs::srv::SetBool::Request>();
288312
request->data = pause;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# SPDX-FileCopyrightText: Alliander N. V.
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
ARG BASE_IMAGE=ubuntu:latest
5+
FROM $BASE_IMAGE
6+
7+
ARG COLCON_BUILD_SEQUENTIAL
8+
ENV ROS_DISTRO=jazzy
9+
10+
# Install adb:
11+
RUN apt update && apt install -y android-tools-adb
12+
13+
# Install srcpy:
14+
RUN apt update && apt install -y \
15+
ffmpeg libsdl2-2.0-0 adb wget gcc git pkg-config meson ninja-build libsdl2-dev libavcodec-dev \
16+
libavdevice-dev libavformat-dev libavutil-dev libswresample-dev libusb-1.0-0 libusb-1.0-0-dev \
17+
&& git clone https://github.com/Genymobile/scrcpy \
18+
&& cd scrcpy \
19+
&& ./install_release.sh
20+
21+
# Install ROS depenencies:
22+
RUN apt update && apt install -y ros-$ROS_DISTRO-moveit-msgs
23+
24+
# Install repo packages:
25+
WORKDIR /$WORKDIR/ros
26+
COPY alliander_core/src/ /$WORKDIR/ros/src
27+
COPY alliander_meta/src/ /$WORKDIR/ros/src
28+
RUN /$WORKDIR/colcon_build.sh
29+
30+
# Install python dependencies:
31+
WORKDIR $WORKDIR
32+
COPY pyproject.toml/ /$WORKDIR/pyproject.toml
33+
RUN uv sync --group alliander-meta \
34+
&& echo "export PYTHONPATH=\"$(dirname $(dirname $(uv python find)))/lib/python3.12/site-packages:\$PYTHONPATH\"" >> /root/.bashrc \
35+
&& echo "export PATH=\"$(dirname $(dirname $(uv python find)))/bin:\$PATH\"" >> /root/.bashrc
36+
37+
# Finalize
38+
WORKDIR /$WORKDIR
39+
ENTRYPOINT ["/entrypoint.sh"]
40+
CMD ["sleep", "infinity"]

alliander_meta/docker-compose.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SPDX-FileCopyrightText: Alliander N. V.
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
services:
5+
alliander_meta:
6+
image: allianderrobotics/meta
7+
container_name: alliander_meta
8+
network_mode: host
9+
privileged: true
10+
mem_limit: 6gb
11+
tty: true
12+
volumes:
13+
- "/tmp/.X11-unix:/tmp/.X11-unix"
14+
- "/dev:/dev"
15+
env_file:
16+
- .env
17+
command: ["/bin/bash", "-c", "ros2 launch alliander_meta meta.launch.py"]

0 commit comments

Comments
 (0)