1. 阿里云服务器申请
阿里云官网地址为https://www.aliyun.com,初次使用请从右上角【注册】入口完成账号创建。正常登录阿里云账号后按下图步骤进入云服务器选购界面:
页面下拉,这里我们选择按量付费方式中的16*CPU+60G+A10的优惠套餐,点击立即抢购,进入系统详情配置页面。
2. 阿里云服务器配置
在云服务器配置页面有以下几点配置需要关注:
2.1. 处理器规格
确认配置是否符合预期:
2.2. 镜像选择
这里我们选择ubuntu22.04 64bit公共基础镜像,同时预装12.8版本CUDA驱动。
2.3. 扩展程序选择
需要选择3.11.12版本及以上的Python版本,这里我们选择的是3.11.12。
2.4. 配置系统盘容量
因为我们采用的CUDA驱动版本是12.8.1,要求系统盘容量在40GB以上,用户可以根据自身需要调整,这里我们调整到60GB。可以看到相比于扩容前的40GB,单位小时内费用仅仅上涨¥0.021。
2.5. 密钥对选择
已有密钥对的用户可以直接在下拉框中选择,初次使用的用户可以点击右侧创建密钥对链接创建。
2.6. 确认下单
配置完成后,在页面右下角可以看到服务器费用,下图中看到的是原价,初次使用的用户享有优惠价格,约¥2/小时。云服务器创建后只有在运行时收费,关机/停止后不计费但会正常保留用户在服务器上的所有修改,只有释放服务器后才会清除。
虽然阿里云优惠后费用很低,但是只有账户余额不少于¥100的前提下才可以完成下单,所以需要提前充值,支持开发票以及余额提现。
云服务器实例创建后即可在账号的工作台中看到,点击会进入云服务器控制台。
2.7. 在线重置root密码
选择云服务器进入实例详情页,在这里可以实现服务器的开机、关机、重启、释放等操作。
在实例详情页中在线充值密码,这个密码就是后续SSH访问云服务器的账号和密码。
3. 阿里云服务器连接
3.1. SSH连接控制台
运行中的云服务器实例在详情页中可以看到其公网IP地址,可以在本地Terminal中通过ssh命令连接:
ssh username@remote_host
3.2. VNC连接服务器桌面
因为阿里云公共基础镜像默认不带桌面,需要用户自行安装,即通过SSH方式连接到服务器后执行安装命令:
sudo apt-get update sudo apt-get install ubuntu-desktop # 设置默认启动图形桌面 sudo systemctl set-default graphical.target # 重启 sudo reboot
如果安装过程中出现报错“unmet dependencies”,运行下方命令后从头重试:
apt-get remove update-manager-core libparted2 python3-update-manager
顺利安装桌面并重启后,可以通过VNC访问桌面。
3.3. 数据传输
可以使用scp命令将本地文件上传到云服务器上,同理也支持将云服务器上文件拉取到本地:
# 拷贝文件 scp /path/to/local/file username@remote_host:/path/to/remote/directory scp username@remote_host:/path/to/remote/file /path/to/local/directory # 拷贝目录 scp -r /path/to/local/directory username@remote_host:/path/to/remote/directory scp -r username@remote_host:/path/to/remote/directory /path/to/local/directory
4. 环境搭建
4.1. ROS2安装
参考官方ROS2 humble版本安装教程:https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html#install-ros-2-packages,顺序执行命令即可。
注意事项:
- ROS2每次运行前都需要设置环境,为了避免忘记,请通过如下命令将环境配置写入.bashrc,此后每次打开一个Terminal都会自动完成ROS2环境配置:
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
- 如果在执行“curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo $VERSION_CODENAME)_all.deb"”时,因为云服务器网络原因无法正常下载的话,可以采用如下方法解决:
- 云服务器上执行echo $(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}'),获取输出,例如1.1.0;
- 云服务器上执行echo $(. /etc/os-release && echo $VERSION_CODENAME),获取输出,例如jammy;
- 将步骤1和步骤2的结果分别替换原curl命令中的${ROS_APT_SOURCE_VERSION}和$(. /etc/os-release && echo $VERSION_CODENAME),替换后的地址例如https://github.com/ros-infrastructure/ros-apt-source/releases/download/1.1.0/ros2-apt-source_1.1.0.jammy_all.deb,将这个地址在本地浏览器打开并保存文件到本地;
- 将上步保存的文件传输到云服务器上;
- 执行命令sudo mv /path/to/step-4/deb/file /tmp/ros2-apt-source.deb;
继续执行后续sudo dpkg -i /tmp/ros2-apt-source.deb命令即可。
4.2. IsaacSim4.5安装
从官方地址https://docs.isaacsim.omniverse.nvidia.com/4.5.0/installation/download.html#下载安装包。
下载完成并上传到云服务器后,参考官方安装教程https://docs.isaacsim.omniverse.nvidia.com/4.5.0/installation/install_workstation.html#workstation-setup,顺序执行命令即可。
mkdir ~/isaacsim cd /Directory/which/containing/your/downloaded/issac-sim/zip/file unzip "isaac-sim-standalone@4.5.0-rc.36+release.19112.f59b3005.gl.linux-x86_64.release.zip" -d ~/isaacsim cd ~/isaacsim ./post_install.sh
4.3. LeRobot机械臂下载
访问https://github.com/TheRobotStudio/SO-ARM100,可以git clone拉取,也可以直接下载zip包。放置到云服务器任意位置并解压(unzip /path/to/your/zip/file)后备用即可。
5. 仿真平台使用
5.1. 仿真平台启动
启动VNC远程桌面连接,桌面右键Open Terminal打开终端命令行,执行位于仿真平台安装目录下的脚本isaac-sim.selector.sh。
在弹出窗口选择ROS2 Bridge和ROS2,并点击START。
如果在主界面启动过程中报如下错误可以不管或者点击Wait。
直到主界面出现并呈现显卡信息和帧率时,仿真平台启动完毕。
5.2. 导入LeRobot机械臂
【File】->【Import】后在弹出菜单中找到章节4.3下载的LeRobot所在目录,并选中文件Simulation/SO101/so101_new_calib.urdf后点击【Import】。
提示确认保存路径时选择Yes。
5.3. 配置仿真环境
删除内建的ArticulationRoot,在机械臂上【右键】->【Add】->【Physics】->【ArticulationRoot】。
创建地板和物理场景。
5.4. 配置工作流
在Graph配置窗口依次拖出On Playback Tick,Articulation Controller, ROS2 Subscribe Joint State三个组件,并按下图方式连接它们:
最后选中Aticulation Controller组件,点击【Add Target...】,选择已导入的机械臂确立绑定关系。
至此,我们可以开始让机械臂持续监听Topic的指令(Topic的Name可以在Subscriber组件中查看并修改):
6. ROS2操控程序
6.1. 创建ROS2工作区
# 1. 安装colcon sudo apt update sudo apt install python3-colcon-common-extensions # 2. 创建工作空间 mkdir -p ~/ros2_ws/src cd ~/ros2_ws/src # 3. 创建lerobot_pkg包 ros2 pkg create --build-type ament_python lerobot_pkg
6.2. 创建Topic Publisher脚本
# 1. 进入lerobot_pkg的源码目录 cd ~/ros2_ws/src/lerobot_pkg/lerobot_pkg # 2. 创建不间断随机发送关节状态指令的Publisher脚本lerobot_publisher.py # ./ros2_ws/ # └── src # └── lerobot_pkg # ├── lerobot_pkg # │ ├── __init__.py # │ └── lerobot_publisher.py # **脚本lerobot_publisher.py放置位置** # ├── package.xml # ├── resource # │ └── lerobot_pkg # ├── setup.cfg # ├── setup.py # └── test # ├── test_copyright.py # ├── test_flake8.py # └── test_pep257.py # 3. 配置入口 # 修改setup.py脚本: # entry_points={ # 'console_scripts': [ # 'lerobot_publisher = lerobot_pkg.lerobot_publisher:main' # ], # }, # 4. 赋予脚本可执行权限 chmod +x ~/ros2_ws/src/lerobot_pkg/lerobot_pkg/lerobot_publisher.py
lerobot_publisher.py源码见下方代码块,其中有两个关键配置一定要注意,无法顺利操控机械臂往往与它们有关:
- "self.create_publisher(JointState, "joint_command", 10)"中joint_command就是Topic Name,需要与章节5.4中配置一致;
- "self.joint_state.name"数组中名称要与仿真平台中机械臂各关节名称保持一致;
import rclpy from rclpy.node import Node from sensor_msgs.msg import JointState import numpy as np import time class TestROS2Bridge(Node): def __init__(self): super().__init__("test_ros2bridge") # 创建发布者。此发布者将发布 JointState 消息到 /joint_command 主题。 self.publisher_ = self.create_publisher(JointState, "joint_command", 10) # 创建 JointState 消息 self.joint_state = JointState() self.joint_state.name = [ "shoulder_pan", "shoulder_lift", "elbow_flex", "wrist_flex", "wrist_roll", "gripper" ] num_joints = len(self.joint_state.name) # 确保 Kit 的编辑器处于播放状态以接收消息 self.joint_state.position = np.array([0.0] * num_joints, dtype=np.float64).tolist() self.default_joints = [0, 0, 0, 0, 0, 0] # 将运动限制在较小范围内(这不是机器人的范围,仅是运动范围) self.max_joints = np.array(self.default_joints) + 0.3 self.min_joints = np.array(self.default_joints) - 0.3 # 使用位置控制让机器人围绕每个关节摆动 self.time_start = time.time() timer_period = 0.05 # 秒 self.timer = self.create_timer(timer_period, self.timer_callback) def timer_callback(self): self.joint_state.header.stamp = self.get_clock().now().to_msg() joint_position = ( np.sin(time.time() - self.time_start) * (self.max_joints - self.min_joints) * 0.5 + self.default_joints ) self.joint_state.position = joint_position.tolist() # 将消息发布到主题 self.publisher_.publish(self.joint_state) def main(args=None): rclpy.init(args=args) ros2_publisher = TestROS2Bridge() rclpy.spin(ros2_publisher) # 显式销毁节点 ros2_publisher.destroy_node() rclpy.shutdown() if __name__ == "__main__": main()
6.3. 编译构建
cd ~/ros2_ws colcon build
colcon build Starting >>> lerobot_pkg Finished <<< lerobot_pkg [1.14s] Summary: 1 package finished [1.55s]
6.4. 启动Topic Publish
cd ~/ros2_ws source install/setup.bash ros2 run lerobot_pkg lerobot_publisher
正常情况下,此时仿真平台机械臂会不断收到来自脚本的运动指令并执行。