Pular para o conteúdo principal

Estágio 7 · Capítulo 33 · Prática

33. Integração do reBot Arm com ROS2

Capítulo 33 do Curso para Iniciantes em IA Física da Seeed — integração prática do reBot Arm com ROS2: criação do workspace ROS2, encapsulamento do SDK em Python em um nó driver, inicialização e visualização do braço no RViz, controle via interfaces de Tópico / Serviço / Ação e parada segura com solução de problemas.

33.1 Criando o Workspace ROS2 do reBot​

Preparação: Ambiente e Hardware​

Antes de começar oficialmente, certifique-se de que o hardware está corretamente conectado e o ambiente de software está pronto. Esta é a base de todas as etapas subsequentes.

  • Fiação de hardware: faça a ponte entre a porta USB2CAN / serial e a placa adaptadora de barramento CAN do braço. Após ligar a alimentação, conecte o USB2CAN ao host e confirme que o sistema reconhece o dispositivo CAN/serial.
  • Sistema operacional: recomenda-se usar Ubuntu 24.04 com ROS2 Jazzy, ou Ubuntu 22.04 com ROS2 Humble.

RS:

sudo ip link set can0 down 2>/dev/null || true
sudo ip link set can0 type can bitrate 1000000
sudo ip link set can0 up

DM:

sudo chmod 666 /dev/ttyACM*

Workspace principal​

Este é o repositório de código principal de todo o trabalho de integração; ele contém todos os componentes necessários para encapsular o reBot Arm como um robô ROS2 padrão.

  • Obter o código: clone o workspace a partir do repositório oficial:
#RS:
git clone https://github.com/Yang-Ci/ReBot_Arm_DigitalTwin_RS.git ~/ReBot_Arm_DigitalTwin_RS

#DM:
git clone https://github.com/Yang-Ci/ReBot_Arm_DigitalTwin_DM.git ~/ReBot_Arm_DigitalTwin_DM

Estrutura do workspace: as versões RS e DM usam nomes de diretório de workspace diferentes (RS é rebotarm_ros2_RS, DM é rebotarm_ros2_DM). Ele contém sete pacotes ROS2 principais:

  • rebotarm_msgs: interfaces personalizadas de mensagem, serviço e ação.
  • rebotarmcontroller: o nó driver, contendo o controlador principal reBotArmController.
  • rebotarm_bringup: arquivos de launch, arquivos de configuração, modelos URDF e recursos do RViz.
  • rebotarm_moveit_config: arquivos de configuração do MoveIt 2.
  • rebotarm_moveit_demos: programas de exemplo do MoveIt 2.
  • rebotarm_mujoco: nó de sincronização de simulação MuJoCo da versão DM (nome do pacote rebotarm_mujoco; a versão RS é rebotarm_mujoco_rs).
  • rebotarm_agent: nó Agent de alto nível da versão DM.

33.2 A Ponte Entre o SDK em Python e o Driver ROS2​

reBotArm_control_py é a biblioteca de controle em Python de baixo nível, e o papel do workspace rebotarm_ros2 é "encapsulá-la" em interfaces ROS2 padrão.

  • Instalar o SDK de baixo nível:

No diretório third_party do workspace, obtenha esta biblioteca de baixo nível (RS fica em rebotarm_ros2/third_party; DM faz a correspondência automaticamente — setup.sh verifica, em ordem, os três caminhos candidatos reBotArmController_ROS2-main/third_party, reBotArmController_ROS2-main/sdk e ~/reBotArm_control_py):

git clone https://github.com/Seeed-Projects/reBotArm_control_py.git third_party/reBotArm_control_py

#reBotArm_control_py's default yaml config is dm; change the one in /reBotArm_control_py/config to the matching option

#RS:
hardware_yaml: "rebotarm_rs.yaml"

#DM:
hardware_yaml: "rebotarm_dm.yaml"
  • Instalar o motorbridge: este é o middleware-chave que conecta os motores ao software de alto nível; instale-o via pip:
python3 -m pip install motorbridge

#verify
motorbridge -v
#output
motorbridge 0.5.0

33.3 Inicialização e Visualização​

  • Verifique os pontos de entrada executáveis:

RS:

cd ~/ReBot_Arm_DigitalTwin_RS/rebotarm_ros2
source install/setup.bash
ros2 pkg executables rebotarmcontroller

DM:

cd ~/ReBot_Arm_DigitalTwin_DM/rebotarm_ros2
source install/setup.bash
ros2 pkg executables rebotarmcontroller
  • Você deve esperar ver pelo menos:
rebotarmcontroller GravityCompensation
rebotarmcontroller GripperControl
rebotarmcontroller MoveTo
rebotarmcontroller MoveToPose
rebotarmcontroller reBotArmController

A versão RS possui dois pontos de entrada executáveis adicionais:

rebotarmcontroller FakeRsDriver        # RS-only: MuJoCo simulation fake driver (fake_rs_driver.py)
rebotarmcontroller CancelAction # RS-only: cancel an executing Action goal

A versão DM possui um ponto de entrada executável adicional:

rebotarmcontroller FakeReBotArmDriver  # DM-only: MuJoCo simulation fake driver (fake_driver.py)

Observação: a versão RS também inclui os dois arquivos de planejamento de movimento motion_profiles.py e trajectory_profiles.py; a versão DM não inclui.

  • Após compilar o workspace, você pode inicializar o sistema completo com um único comando, conectando o controle do braço, a publicação de estado e a visualização.
# Build the workspace
source /opt/ros/${ROS_DISTRO}/setup.bash
colcon build --symlink-install
source install/setup.bash

# Launch the full system and enable RViz visualization
# RS:
cd ~/ReBot_Arm_DigitalTwin_RS/rebotarm_ros2
ros2 launch rebotarm_bringup bringup.launch.py model:=rs channel:=can0 use_rviz:=true

# DM:
cd ~/ReBot_Arm_DigitalTwin_DM
./rebotarm start dm use_rviz:=true
  • Publicação de estado: após a inicialização, o nó reBotArmController publica continuamente o estado do braço, por exemplo, estados das juntas (/rebotarm/joint_states) e status geral (/rebotarm/arm_status).
#show active topic names
ros2 topic list
#list topics and their message types; adding the -t flag also shows each topic's message type:
ros2 topic list -t
#example output:
/client_count
/connected_clients
/goal_pose
/initialpose
/parameter_events
/rebotarm/arm_status
/rebotarm/control_reference
/rebotarm/control_target
/rebotarm/gripper/cmd/mit
/rebotarm/gripper/cmd/pos_vel
/rebotarm/gripper/state
/rebotarm/joint_states
/rebotarm/joints/joint1/cmd/mit
/rebotarm/joints/joint1/cmd/pos_vel
/rebotarm/joints/joint1/state
/rebotarm/joints/joint2/cmd/mit
/rebotarm/joints/joint2/cmd/pos_vel
/rebotarm/joints/joint2/state
/rebotarm/joints/joint3/cmd/mit
/rebotarm/joints/joint3/cmd/pos_vel
/rebotarm/joints/joint3/state
/rebotarm/joints/joint4/cmd/mit
/rebotarm/joints/joint4/cmd/pos_vel
/rebotarm/joints/joint4/state
/rebotarm/joints/joint5/cmd/mit
/rebotarm/joints/joint5/cmd/pos_vel
/rebotarm/joints/joint5/state
/rebotarm/joints/joint6/cmd/mit
/rebotarm/joints/joint6/cmd/pos_vel
/rebotarm/joints/joint6/state
/rebotarm/mujoco/object_states
/rebotarm/mujoco/overhead_rgb/image_raw
/rebotarm/sim/animation_event
/rebotarm/vision/color_blocks/detections
/robot_description
/rosout
/tf
/tf_static
  • Exibição no RViz: por meio do RViz, você pode observar o braço baseado em URDF se mover em tempo real, obtendo um efeito de monitoramento "o que você vê é o que você obtém".
O modelo do reBot arm exibido no RViz

Após a inicialização, o nó reBotArmController publica continuamente o estado do braço. A publicação de estado é gerenciada de forma unificada pela classe JointStatePublisher (ros_publishers.py), acionada por um temporizador em uma frequência configurável (100 Hz por padrão), sem necessidade de gatilho externo.

Visão geral dos tópicos publicados:

TopicMessage typeDescription
/rebotarm/joint_statessensor_msgs/msg/JointStatePosição, velocidade e torque das 6 juntas, além do gripper finger_left
/rebotarm/arm_statusrebotarm_msgs/msg/ArmStatusModo de controle, estado de habilitação, máquina de estados, códigos de status por junta, códigos de erro (QoS latched)
/rebotarm/joints/<joint>/staterebotarm_msgs/msg/JointMotorStateEstado em nível de motor de uma única junta; <joint> é de joint1 a joint6
/rebotarm/gripper/staterebotarm_msgs/msg/JointMotorStateEstado em nível de motor do gripper; não é publicado quando nenhum gripper está configurado

A mensagem ArmStatus usa durabilidade TRANSIENT_LOCAL (QoS latched), o que significa que assinantes que entram depois recebem imediatamente o snapshot mais recente de estado — adequado para componentes de UI e monitoramento de integridade sincronizarem o estado:

# View joint states
ros2 topic echo /rebotarm/joint_states --once

# View overall status (including state machine and error codes)
ros2 topic echo /rebotarm/arm_status --once

# View a single joint's motor state
ros2 topic echo /rebotarm/joints/joint1/state --once

Campos da mensagem ArmStatus:

std_msgs/Header header
string mode # current control mode: mit / pos_vel / vel
bool enabled # whether the arm is enabled
bool control_loop_active # whether the internal pos_vel control loop is running
string state_machine # state machine: IDLE / TRAJ_RUNNING / LOWLEVEL_STREAMING / GRAVITY_COMP
string[] joint_names # list of joint names
uint8[] per_joint_status_code # status code of each joint motor
string[] error_codes # list of error codes

33.4 Controle por Tópico, Serviço e Ação​

rebotarm_ros2 fornece uma variedade de interfaces de controle padrão ROS2 para escolha com base no cenário de aplicação. Todas as interfaces estão sob o namespace /rebotarm por padrão, podendo ser sobrescrito por meio do parâmetro de launch arm_namespace.

Unifique as unidades antes do controle: ângulos em radianos (rad); tempo em segundos.

Fluxo de exemplo para controle via Topic, Service e Action​

#1 Power on and enable the motors
ros2 service call /rebotarm/enable std_srvs/srv/Trigger
#2 Return to the safe home (verify the zero position is correct)
ros2 service call /rebotarm/safe_home std_srvs/srv/Trigger
# Now you can send move_to_pose / follow_joint_trajectory action goals
# ...execute motion...
# Disable after finishing
ros2 service call /rebotarm/disable std_srvs/srv/Trigger

Topic: passagem direta de baixo nível para motor único​

Para depuração e experimentos de controle de baixo nível, motor_passthrough.py fornece topics de comando bruto esparsos por junta:

TopicTipo de mensagemDescrição
/rebotarm/joints/<joint>/cmdrebotarm_msgs/msg/JointMotorCmdComando bruto esparso de junta única
/rebotarm/gripper/cmdrebotarm_msgs/msg/JointMotorCmdComando bruto esparso do gripper

JointMotorCmd usa um design com sinalizadores esparsos: somente os campos cujos use_pos, use_vel, use_kp, use_kd, use_tau, use_vlim são true substituem os padrões. mode pode ser 0 (MIT), 1 (POS_VEL), 2 (VEL).

# Single-joint MIT mode command
ros2 topic pub --once /rebotarm/joints/joint1/cmd/mit \
rebotarm_msgs/msg/JointMitCmd \
"{pos: 0.2, vel: 0.0, kp: 80.0, kd: 4.0, tau: 0.0}"

Durante a execução de trajetória, o comando de baixo nível é rejeitado por padrão (cmd_arbitration:=reject). Para substituição preemptiva, passe cmd_arbitration:=preempt no lançamento.

Service: controle em estilo de gatilho​

Service é adequado para operações em estilo de gatilho, como habilitar/desabilitar, homing seguro e troca de modo. Ele é definido na classe ArmServices de ros_services.py.

ServiceTipoDescrição
/rebotarm/enablestd_srvs/srv/TriggerHabilita o braço e o gripper, inicia o loop de controle pos_vel
/rebotarm/disablestd_srvs/srv/TriggerPara o loop de controle e desabilita o braço
/rebotarm/safe_homestd_srvs/srv/TriggerRetorna ao zero em velocidade segura (juntas + gripper)
/rebotarm/set_zerorebotarm_msgs/srv/SetZeroDefine a posição zero de todas ou de juntas especificadas
/rebotarm/move_to_pose_ikrebotarm_msgs/srv/MoveToPoseIKApenas realiza a solução de IK e atualiza os ângulos de junta alvo
/rebotarm/gripper/setrebotarm_msgs/srv/SetGripperDefine a distância de abertura do gripper e o torque máximo
/rebotarm/gravity_compensation/startstd_srvs/srv/TriggerInicia o loop fechado de compensação de gravidade interno ao controlador
/rebotarm/gravity_compensation/stopstd_srvs/srv/TriggerPara o loop fechado de compensação de gravidade
/rebotarm/gravity_compensation/statusstd_srvs/srv/TriggerConsulta o status da compensação de gravidade; success=true significa em execução

Exemplos comuns de comando:

# Enable
ros2 service call /rebotarm/enable std_srvs/srv/Trigger

# Safe homing
ros2 service call /rebotarm/safe_home std_srvs/srv/Trigger

# IK solve (!!! note the arm moves very fast)
ros2 service call /rebotarm/move_to_pose_ik rebotarm_msgs/srv/MoveToPoseIK \
"{target_pose: {position: {x: 0.30, y: 0.0, z: 0.30}, orientation: {w: 1.0}}}"

# Send a Cartesian pose goal (3 s total motion time)
ros2 action send_goal /rebotarm/move_to_pose rebotarm_msgs/action/MoveToPose \
"{target_pose: {position: {x: 0.30, y: 0.0, z: 0.30}, orientation: {w: 1.0}}, duration: 3.0}"

# Set the gripper opening (rad; 0-5)
ros2 service call /rebotarm/gripper/set rebotarm_msgs/srv/SetGripper \
"{position: 2.5, max_effort: 0.5}"

# DM
ros2 service call /rebotarm/gripper/set \
rebotarm_msgs/srv/SetGripper "{position: -1.0, max_effort: 0.0}"

Action: controle orientado a processo​

Action é adequado para movimentos de longa duração que exigem feedback e cancelamento, como execução de trajetória. Ele é definido na classe ArmActions de ros_actions.py.

ActionTipoDescrição
/rebotarm/move_to_poserebotarm_msgs/action/MoveToPoseTrajetória de pose cartesiana do efetuador final; internamente usa ArmEndPos.move_to_traj()
/rebotarm/follow_joint_trajectorycontrol_msgs/action/FollowJointTrajectoryInterface padrão de trajetória de juntas; interface padrão do MoveIt2
/rebotarm/gripper/commandcontrol_msgs/action/GripperCommandAction padrão de gripper

Exemplo de move_to_pose: enviar uma meta de movimento para o serviço Action do reBot Arm — mover o braço para uma pose especificada, manter o tempo total de movimento em 3 segundos e imprimir o feedback em tempo real durante o movimento.

ros2 action send_goal /rebotarm/move_to_pose rebotarm_msgs/action/MoveToPose \
"{target_pose: {position: {x: 0.30, y: 0.0, z: 0.30}, orientation: {w: 1.0}}, duration: 3.0}" \
--feedback

Ver a definição de mensagem da Action

ros2 interface show rebotarm_msgs/action/MoveToPose
#You can see the complete Goal / Feedback / Result fields.

Exemplos de Demonstração​

Todos os exemplos assumem que reBotArmController já foi iniciado:

cd ~/seeed/rebotarm_ros2
source /opt/ros/jazzy/setup.bash
source install/setup.bash
ros2 launch rebotarm_bringup bringup.launch.py channel:=/dev/ttyACM0

Os exemplos são registrados como entry points executáveis ROS2 e podem ser chamados diretamente com ros2 run. Os arquivos-fonte estão em src/rebotarmcontroller/rebotarmcontroller/examples/.

Exemplo de Pose do Efetuador Final​

move_to_pose.py — movimento de pose do efetuador final. O script envia uma meta geometry_msgs/Pose através da action /rebotarm/move_to_pose; o nó de controle lida internamente com a troca de modo e a execução da trajetória. Ele corresponde à cadeia de capacidades ArmEndPos.move_to_traj() do SDK de baixo nível. É uma demonstração de ação única e não executa automaticamente safe_home ou disable.

ros2 run rebotarmcontroller MoveToPose -- --x 0.30 --y 0.0 --z 0.30 --qw 1.0 --duration 2.0

Exemplo de Compensação de Gravidade​

gravity_compensation.py — um exemplo de trava de compensação de gravidade. O script não reescreve o loop de controle; ele chama diretamente o serviço de compensação de gravidade dentro de reBotArmController; o loop fechado real de compensação de gravidade é executado dentro do processo do controlador, usando o RobotArm.get_positions/get_velocities/mit do SDK.

ros2 run rebotarmcontroller GravityCompensation

Quando o script inicia, ele primeiro chama /rebotarm/enable, depois inicia a compensação de gravidade. Ao sair com Ctrl+C, o script chama sequencialmente /rebotarm/gravity_compensation/stop → /rebotarm/safe_home → /rebotarm/disable, então o braço primeiro para a compensação de gravidade, depois retorna à posição zero segura e é desabilitado.

33.5 Parada Segura e Solução de Problemas​

A segurança é a primeira prioridade na operação de robôs. rebotarm_ros2 fornece mecanismos de segurança em vários níveis.

safe_home service: via o serviço /rebotarm/safe_home, o braço retorna à posição zero predefinida em velocidade segura.​

Internamente, esse serviço primeiro para a compensação de gravidade, depois alterna para o modo pos_vel e então executa o homing:

ros2 service call /rebotarm/safe_home std_srvs/srv/Trigger

disable service: para o loop de controle e desabilita o braço; é a primeira escolha para parada de emergência​

ros2 service call /rebotarm/disable std_srvs/srv/Trigger

hold_current_position: quando uma trajetória é cancelada ou ocorre uma exceção, o controlador chama automaticamente esse método para travar as posições atuais das juntas, evitando que o braço caia livremente.

Monitoramento da máquina de estados​

O campo state_machine no topic /rebotarm/arm_status reflete o estado de execução atual e é o primeiro ponto de entrada para solução de problemas:

EstadoSignificado
IDLEOcioso, aguardando comandos
TRAJ_RUNNINGExecutando uma trajetória
LOWLEVEL_STREAMINGTransmitindo comandos de baixo nível para motor único
GRAVITY_COMPLoop fechado de compensação de gravidade em execução
# Continuously monitor the state machine
ros2 topic echo /rebotarm/arm_status --field state_machine

Solução de problemas por código de erro​

Os campos per_joint_status_code e error_codes na mensagem ArmStatus são usados para localização de falhas:

per_joint_status_code: código de status (uint8) de cada motor de junta, vindo de motor.get_state().status_code do SDK de baixo nível; um valor diferente de zero significa que o motor está anormal. error_codes: strings de código de erro em nível de controlador

# View the full status (including error codes)
ros2 topic echo /rebotarm/arm_status --once

33.6 FAQ: Problemas Comuns e Solução de Problemas​

Porta serial não encontrada: ao iniciar, aparece open serial port /dev/ttyACM0 failed; use ls /dev/ttyACM*​

para ver o dispositivo real e então sobrescreva com channel:=/dev/ttyACM1.

Permissões insuficientes: se a porta serial existir mas você não tiver permissão, execute sudo usermod -a -G dialout $USER,

e isso terá efeito após fazer login novamente.

Modelo RViz não exibido: confirme que o caminho da malha URDF é package://rebotarm_bringup/description/meshes/....​

Execução de trajetória falhou: verifique se o primeiro ponto da trajetória está próximo dos ângulos de junta atuais (o desvio deve ser menor que 0.10 rad),​

e o erro de posição final deve ser menor que 0.03 rad. Você pode usar ros2 topic echo /rebotarm/joint_states --once

para ver os ângulos de junta atuais.

Loading Comments...