
1. 拿到G1之后为什么第一件事是打通SSH而不是急着跑Demo刚拿到宇树G1的开发者十有八九会先翻官方文档找运动控制例程恨不得十分钟内就让机器人站起来走两步。但真正在项目里摸爬滚打过的人都知道在机器人本体上直接插显示器键鼠调试是一件极其折磨人的事——G1的算力单元通常藏在机身内部接口位置刁钻你不可能每次都趴在地上接HDMI。所以我的习惯是新机器到手先不碰任何业务代码集中精力把SSH远程通道打通把VSCode远程开发环境搭起来。这一步做扎实了后面所有调试都是坐在自己工位上完成的。SSHSecure Shell在这里扮演的角色本质上是给你的开发机和G1之间修一条加密隧道。你在这头敲命令那头执行输出再传回来。听起来简单但G1这类机器人平台的网络环境有几个特殊之处它可能跑的是定制Linux不少国产机器人用的是openEuler或麒麟系网络配置方式和你在Ubuntu上熟悉的netplan完全不是一回事它可能默认没有图形界面你连IP都不知道它的网口可能只有一个还和内部通信复用。这些坑我几乎全踩过一遍所以这篇就把从IP配置到VSCode远程开发的完整链路拆开讲重点放在那些文档里不会写、但实际一定会遇到的问题上。这篇文章适合三类人刚拿到G1准备做二次开发的工程师、被机器人网络配置卡住的中级开发者、以及想把自己调试流程规范化的团队。我会尽量把每一步的“为什么”讲清楚而不是只丢一串命令让你抄。毕竟机器人这东西环境一变抄来的命令大概率跑不通理解原理才能自己排错。2. 先搞清楚G1的网络家底接口、系统与默认状态2.1 G1常见的网络接口形态与对应策略宇树G1不同批次和配置网络接口的形态不完全一样。我接触过的机器里主要有这么几种情况机身带一个RJ45千兆网口、通过USB转网口扩展、或者干脆只有WiFi模块。你得先确认自己手上这台是哪种因为这直接决定了你的连接策略。如果机身有原生RJ45网口那是最省事的一根网线直连你的开发机或者接到同一台交换机上就行。但要注意很多机器人出厂时这个网口是配置成DHCP自动获取的你根本不知道它拿到了什么IP。这时候有两个办法一是登录路由器后台看DHCP租约列表找到对应MAC地址的条目二是用arp-scan或者nmap扫一遍局域网。我一般用后者命令是sudo nmap -sn 192.168.1.0/24扫完看哪个IP的MAC地址前缀和机器人网口对得上。如果只有WiFi那事情会麻烦一点因为你要先让机器人连上你的网络。有些G1出厂会开一个热点你用手机或电脑连上去然后通过默认网关地址通常是192.168.4.1或192.168.12.1这类访问它的配置页面。但更常见的情况是它根本没开热点你得通过串口或者机身屏幕去配WiFi。这就引出了下一个问题系统是什么。2.2 openEuler与麒麟系系统的网络配置差异G1的算力单元跑的系统我见过openEuler、银河麒麟V10、也有Ubuntu 20.04的。这三个系统的网络配置方式差别不小尤其是前两个国产系统很多开发者不熟悉容易在这里卡住。openEuler用的是NetworkManager或者systemd-networkd具体看版本。你可以先用nmcli device status看看网络管理工具是哪个。如果是NetworkManager配置静态IP的命令是nmcli con mod 有线连接 1 ipv4.addresses 192.168.1.100/24 nmcli con mod 有线连接 1 ipv4.gateway 192.168.1.1 nmcli con mod 有线连接 1 ipv4.dns 8.8.8.8,114.114.114.114 nmcli con mod 有线连接 1 ipv4.method manual nmcli con up 有线连接 1注意连接名称要用nmcli con show查出来的实际名称别照抄“有线连接 1”。麒麟V10也类似但它有时候会用自己的一套网络配置工具图形界面下好办命令行下还是走nmcli居多。这里有个坑我踩过openEuler某些版本默认没装NetworkManager用的是systemd-networkd。这时候你得去改/etc/systemd/network/下面的.network文件格式和netplan完全不同。判断方法很简单systemctl status NetworkManager看服务在不在跑不在的话大概率就是networkd。2.3 没有显示器和IP时怎么摸进后台这是最让人头大的场景机器人没接显示器你也不知道它IP网络配置还是错的。这时候别慌有几条路可以走。第一条路是串口。G1的算力单元通常引出了调试串口UART你用USB转TTL线接上波特率一般是115200用screen /dev/ttyUSB0 115200或者minicom就能进控制台。进去之后用ip addr看网口状态用nmcli或直接改配置文件都行。这是最可靠的方式因为不依赖网络。第二条路是网线直连加抓包。你把开发机和G1用网线直连开发机设一个同网段的静态IP然后tcpdump抓包看G1有没有发ARP或者DHCP请求。如果它在发DHCP Discover说明它想自动获取IP你可以在开发机上临时起一个DHCP服务给它分配地址。这招稍微绕但应急时管用。第三条路是看机身有没有USB接口能接键盘有些G1预留了USB口你插个键盘盲操也行但没显示器还是看不到输出所以基本不实用。综合下来串口是首选建议拿到机器第一件事就是确认串口线序和波特率把它当成保底通道。3. 静态IP配置让G1的地址固定下来3.1 为什么必须配静态IP而不是依赖DHCPDHCP方便是方便但对机器人开发来说是个隐患。你想想你今天连上去调好了代码明天开机IP变了VSCode的远程连接配置全得改脚本里的地址也得跟着换烦不烦更麻烦的是如果你写了自动化部署脚本IP一变直接全挂。所以只要这台G1是固定放在实验室或工位上用的静态IP是必须的。配静态IP还有个好处你可以把IP规划进自己的网段体系。比如我习惯把机器人放在192.168.1.200-192.168.1.250这个区间开发机用100-150网关和路由器用1-10。这样一看IP就知道是什么设备排查问题快很多。3.2 openEuler下配置静态IP的完整流程假设你已经通过串口或临时连接进了系统现在要配静态IP。先确认网口名称ip link show输出里类似enp3s0、eth0、enx00e04c680xxx的就是网口名。记住它下面要用。如果用NetworkManager按2.2节里的nmcli命令走就行。但我要补充几个细节ipv4.dns可以配多个用逗号隔开ipv4.method manual这步千万别漏否则前面配的地址不生效改完之后用nmcli con up重新激活连接或者nmcli con reload再up。如果用systemd-networkd创建或编辑/etc/systemd/network/10-static.network[Match] Nameenp3s0 [Network] Address192.168.1.200/24 Gateway192.168.1.1 DNS8.8.8.8 DNS114.114.114.114然后systemctl restart systemd-networkd再用networkctl status enp3s0确认地址生效。这里有个容易忽略的点openEuler的防火墙默认可能是开着的你配好IP但SSH连不上先别怀疑网络查一下防火墙。firewall-cmd --list-all看看ssh服务有没有放行没有的话firewall-cmd --add-servicessh --permanent firewall-cmd --reload。3.3 麒麟V10配置双IP的注意事项有些项目需要G1同时接入两个网络比如一个连控制网、一个连数据网这就涉及配双IP。麒麟V10下可以用nmcli给同一个网口加多个地址nmcli con mod 有线连接 1 ipv4.addresses 192.168.2.200/24注意那个号表示追加而不是覆盖。加完之后重新激活连接。但这里有个坑两个网段的网关不能冲突你只能给一个网段配默认网关另一个网段要么走静态路由要么就不配网关只做直连通信。我见过有人两个网段都配了网关结果路由表乱了两个网络都时通时断。另外麒麟V10对SELinux的管理比较严如果你改了网络配置文件后服务起不来看看/var/log/audit/audit.log里有没有SELinux拒绝记录有的话用ausearch -m avc -ts recent查详情必要时调整策略或临时设成permissive排查。4. SSH服务端配置让G1接受远程连接4.1 确认SSH服务状态与放行端口IP配通了下一步是确保G1上的SSH服务在跑。systemctl status sshd看一眼没跑就systemctl start sshd并systemctl enable sshd设成开机自启。然后确认监听端口默认22但有些定制系统会改。ss -tlnp | grep ssh能看到实际端口。如果服务在跑但连不上按这个顺序查防火墙有没有放行、/etc/ssh/sshd_config里PermitRootLogin和PasswordAuthentication的设置、以及有没有AllowUsers限制。我遇到过一台G1出厂配置里AllowUsers只允许一个特定用户你用别的账号怎么都连不上改成允许你的用户或者注释掉这行才行。4.2 密钥登录配置比密码安全且省事密码登录每次都要输而且脚本里嵌密码不安全。配密钥登录是一劳永逸的事。在开发机上生成密钥对ssh-keygen -t ed25519 -C g1-dev一路回车默认存在~/.ssh/id_ed25519。然后把公钥推到G1上ssh-copy-id -i ~/.ssh/id_ed25519.pub user192.168.1.200如果ssh-copy-id不可用就手动把公钥内容追加到G1的~/.ssh/authorized_keys里。注意权限.ssh目录必须是700authorized_keys必须是600权限不对SSH会拒绝使用密钥。这个坑在Windows上尤其常见如果你把密钥文件放在NTFS分区权限继承会出问题报错类似bad owner or permissions on .../.ssh/config。解决办法是把密钥放到WSL或者用icacls手动改权限。配好之后测试ssh user192.168.1.200能免密进去就成功了。然后建议把sshd_config里的PasswordAuthentication改成no只留密钥登录安全性提升一大截。4.3 用主机名代替IP配置SSH config每次输IP也烦可以在开发机的~/.ssh/config里加一段Host g1 HostName 192.168.1.200 User ubuntu IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 60之后直接ssh g1就能连。ServerAliveInterval 60是防止连接空闲被断开机器人调试时经常挂着连接去干别的这个参数很实用。如果你有多台G1就配多个Host条目名字区分开比如g1-arm、g1-base。5. VSCode远程开发环境搭建把IDE搬到G1上5.1 Remote-SSH插件的安装与连接VSCode远程开发的核心是Remote-SSH插件。在扩展市场搜“Remote - SSH”装上然后按F1输入“Remote-SSH: Connect to Host”选你配好的g1VSCode会在G1上自动安装vscode-server。第一次连接会慢一点因为要下载server组件如果G1不能直连外网你得手动下载vscode-server的离线包传上去。连接成功后VSCode左下角会显示“SSH: g1”这时候你打开的任何文件夹、终端、调试会话都是在G1上执行的。这意味着你可以在本地VSCode里写Python代码直接调用G1上的机器人SDK断点调试也在G1上跑体验和本地开发几乎一样。这里有个网络细节VSCode Remote-SSH默认走22端口如果你改了SSH端口在config里加Port 2222这样的配置就行。另外如果G1和开发机之间网络延迟高VSCode的响应会有点卡建议在config里加Compression yes开启压缩能改善不少。5.2 在远程环境里配Python和C开发环境G1的二次开发通常涉及Python调SDK和C性能敏感部分。远程连上后Python环境建议用conda或venv隔离别直接动系统Python。python3 -m venv ~/g1-env source ~/g1-env/bin/activate然后在VSCode里选这个解释器。C的话装C/C扩展配c_cpp_properties.json里的includePath指向G1上的SDK头文件目录。编译用CMake的话在远程终端里跑cmake和makeVSCode的终端本身就是远程的所以直接操作就行。调试配置写在.vscode/launch.json里program路径填G1上的可执行文件路径miDebuggerPath填G1上的gdb路径。我建议把.vscode目录也纳入版本管理这样团队里每个人连上同一台G1后开发环境配置是一致的省得各自配一遍还配出差异。5.3 远程开发中常见的连接中断与重连处理机器人调试时G1可能会因为各种原因重启或者网络抖动VSCode远程连接就断了。这时候别急着重启VSCode先看右下角有没有“Reconnect”按钮有的话点一下通常能恢复。如果不行F1输入“Remote-SSH: Kill VS Code Server on Host”清掉服务端残留再重连。更彻底的办法是在SSH config里加ServerAliveInterval 30和ServerAliveCountMax 3让客户端定期发心跳减少被中间网络设备断开的概率。如果G1经常重启可以考虑写个systemd服务让vscode-server开机自启不过这个稍微复杂一般用不到。6. 那些文档不会告诉你的踩坑实录6.1 SSH连接超时但ping得通防火墙与路由的排查链路这个现象很迷惑ping 192.168.1.200通但ssh就是超时。我遇到过好几次排查下来原因各不相同。第一次是G1的防火墙拦了22端口但ICMP放行了所以ping通SSH不通。firewall-cmd --list-all一看ssh服务确实没在allowed列表里。加上就好了。第二次更隐蔽G1配了双网卡默认路由走的是另一个网段你从开发机来的包能到G1但G1的回包走了错误的网口导致TCP握手完不成。用ip route get 192.168.1.100看G1认为去开发机的路由走哪个网口如果不是你期望的那个就得调整路由优先级或者加策略路由。第三次是中间交换机做了端口隔离同一交换机下的两个口不能互通。这种就得换口或者改交换机配置。排查这类问题tcpdump是你的好朋友在G1上tcpdump -i any port 22看有没有收到SYN包收到了有没有回SYN-ACK一步步缩小范围。6.2 密钥登录报权限错误的根因与修复bad owner or permissions on ~/.ssh/config这个报错Windows、Mac、Linux上都可能出现根因都是文件权限不符合SSH的严格要求。Linux/Mac下chmod 600 ~/.ssh/config chmod 700 ~/.ssh就行。Windows下如果用的是OpenSSH它检查的是NTFS ACL你得用icacls命令把权限收紧到只有当前用户可读写。还有一种情况是密钥文件本身权限太开比如从U盘拷过来默认是777SSH会拒绝使用。chmod 600 id_ed25519解决。我建议养成习惯密钥文件生成后立刻改权限别等报错了再查。6.3 G1重启后IP丢失或SSH服务未自启的预防有些G1重启后静态IP没了变回DHCP。这通常是NetworkManager的连接配置没设成autoconnect或者配置文件写错了位置。nmcli con show看连接的autoconnect是不是yes不是的话nmcli con mod 有线连接 1 connection.autoconnect yes。SSH服务没自启就是systemctl enable sshd没做。这两个问题都属于“配的时候好好的重启就废”建议配完网络和SSH后主动重启一次G1验证别等到正式跑实验时才发现。7. 把这套流程固化成团队规范一个人调通不算本事让团队里每个人拿到G1都能快速上手才是价值。我的做法是写一份内部checklist包含串口线序和波特率、静态IP规划表、SSH密钥分发流程、VSCode远程配置模板。新机器到手照着checklist走一遍半小时内就能进入开发状态。另外建议把G1的网络配置和SSH配置做成脚本放在版本库里。新机器或者重装系统后跑一遍脚本就恢复环境。脚本里注意把IP、主机名这些变量抽出来不同机器用不同的配置文件覆盖别硬编码。最后分享一个我自己的习惯每台G1的机身或者包装上贴一张标签写上主机名、静态IP、SSH端口、串口波特率。别小看这张标签实验室里机器一多没有它你根本分不清哪台是哪台每次都要重新查浪费时间。这套流程跑顺之后你会发现机器人开发的大部分时间都花在算法和业务上而不是和环境搏斗。