BalanceBot 安卓遥控 App 深度解析:轮腿机器人的摇杆遥控、MJPG 图传与蓝牙配网实现 机器人嵌入式硬件开发移动开发【免费下载链接】foc-wheel-legged-robotOpen source materials for a novel structured legged robot, including mechanical design, electronic design, algorithm simulation, and software development. | 一个新型结构的轮腿机器人开源资料包含机械设计、电子设计、算法仿真、软件开发等材料项目地址https://gitcode.com/gh_mirrors/fo/foc-wheel-legged-robot点击查看免费下载本文基于 foc-wheel-legged-robot 仓库中android/子模块的官方文档README_en.md结合 MainActivity.java、CtrlView.java、ctrl-proxy.py 等源码完整还原这套 Android 遥控应用的显示方案、图传连接时序与蓝牙配网协议。读完本文你将理解如何仅用一个重写的 WebView 同时承载视频显示与触摸遥控以及如何通过 BLE 文本协议让图传系统自动入网掌握一套可直接借鉴的App Linux 图传 嵌入式主控三级无线链路设计。一、模块定位与三大功能android/是轮腿机器人项目的子模块基于 Android Studio 开发工程名BalanceBotapplicationId 为com.skythinker.balancebot提供三项核心功能读取用户触摸输入向机器人发送遥控指令拉取图传系统linux-fpv/ 模块的视频流并显示在界面上配合图传系统进行蓝牙配网Bluetooth pairing使图传系统自动接入指定 WiFi。项目同时提供了预编译安装包 balancebot.apk可直接安装使用如需二次开发仓库保留了完整的 Gradle 工程settings.gradle、build.gradle。二、显示方案重写 WebView 实现视频 控件双层叠加文档指出由于图传系统输出的 MJPG 视频流可以直接在各种浏览器中访问因此 App 直接利用一个 WebView 作为主显示视图仅需少量 HTML JavaScript 代码即可显示视频流同时重写 WebView 的onDraw方法在 HTML 页面上方叠加绘制摇杆、滑块等控件并通过onTouchEvent方法监听用户触摸输入。2.1 视频流页面 streamview.html视频流页面位于 assets/streamview.html其关键实现通过setServerIP(ip)函数把视频源切换为http://ip:8090/camera.mjpg即图传系统上 ffserver 的 MJPG 推流地址与 linux-fpv/README_en.md 中camera.mjpg端点一致使用img标签直接承载 MJPG 流并在onerror时回退到本地 transparent.png 透明图用于占位每 3 秒定时刷新一次图片地址并通过 WebView JS 接口webview.jsCallback(setVideoState, true/false)向 Native 层反馈视频是否连通页面内以ASPECT_RATIO 4/3自适应缩放视频区域。对应的 Native 侧代码在 CtrlView.java 中构造函数里启用 JavaScript、加载本地页面并注册交互接口L62-L64getSettings().setJavaScriptEnabled(true); //启用JavaScript loadUrl(file:///android_asset/streamview.html); //加载本地HTML页面 addJavascriptInterface(this, webview); //创建WebView交互接口jsCallback方法L67-L76收到setVideoState消息后更新videoConnected标志并invalidate()重绘这就是界面上视频状态灯的数据来源。当配网拿到图传 IP 后setServerIP方法L226-L234会执行loadUrl(javascript:setServerIP(ip))反向调用 HTML 函数完成视频源切换。2.2 叠加控件的绘制与触摸CtrlView继承自WebViewonDraw先调用super.onDraw(canvas)绘制 WebView 内容再依次叠加绘制L80-L125状态标识 配置按钮左上角圆角矩形内显示蓝牙/视频连接状态图标bt_on.png / video_off.png 等摇杆加载 rocker.png 底图按rockerValueX/Y偏移绘制摇杆中心点滑块横向圆角轨道 圆形滑块用于调节腿部长度左下角文字提示显示正在扫描设备…、WiFi连接成功…等状态文字。setSize方法L237-L250根据屏幕宽高计算各控件矩形区域摇杆位于右下角滑块位于其上方配置按钮固定在左上角 (100, 0)-(200, 100)。onTouchEventL128-L223实现了一套轻量级命中检测按下时判断触点落在摇杆圆内、滑条内还是配置按钮内分别置位rockerDown/sliderDown/configDown拖动摇杆时做了越界收缩把落点拉回圆内并归一化到 -1.0~1.0同时存在死区逻辑——当|rockerValueY/rockerValueX| 0.4时把纵向分量清零或横向清零保证摇杆在纯前进或纯转向两个轴向上输出更干净摇杆抬起即归零复位滑块则保持松手位置配置按钮在按下区域内侧松开才触发callback.onUserInput(click, config)交回MainActivity弹出操作菜单。这套HTML 画视频 Canvas 画控件 统一 onTouchEvent 分发的做法避免了为视频帧做 Java 层解码是文档所述显示方案的精髓。三、图传连接方案视频流 UDP 遥控双链路文档提示图传系统的通信链路细节请先参阅 linux-fpv/README_en.md 中的 Connection Scheme 一节。该方案是即插即用的双场景设计不使用图传App 直接通过蓝牙与主控模块ESP32蓝牙名BalanceBot收发遥控数据使用图传图传系统NanoPI蓝牙名NanoPI一方面与 App 通过局域网交互另一方面通过蓝牙连接主控模块把 App 发来的遥控数据转发给主控同时把视频流推给 App。此时 App 与机器人无需处于蓝牙范围内只需同在一个局域网即可。注图中上位机表示本 App运动控制模块表示机器人主控模块。3.1 视频链路App 直接 HTTP 拉流视频不需要经过蓝牙或 UDPApp 中的 WebView 直接向http://NanoPI IP:8090/camera.mjpg发起 HTTP 请求获取 MJPG 流对应 streamview.html 中setServerIP的实现。推流端由 NanoPI 上的mjpg-ffserver服务提供见 linux-fpv/scripts/ffserver.conf。3.2 UDP 遥控链路10Hz 的 4 字节遥控帧遥控数据走 UDP。App 侧由 WifiClient.java 封装本地绑定端口15000默认目标端口5000内部用阻塞式DatagramSocket.receive线程轮询接收L15-L17、L28-L46。MainActivity中创建一个独立发送线程MainActivity.java L225-L256以 100ms 周期10Hz构造遥控帧final byte BT_FRAME_HEADER (byte) 0xAA; //遥控数据帧头 byte[] btData new byte[]{ BT_FRAME_HEADER, (byte) ((ctrlView.rockerValueX 1) * 100), (byte) ((ctrlView.rockerValueY 1) * 100), (byte) ((ctrlView.sliderValue 1) * 100) }; if(btCtrl.isConnected) { btCtrl.sendBytes(btData); //蓝牙模式直发主控模块 } else { wifiClient.sendBytes(btData); //图传模式发往NanoPI的UDP服务器 }帧格式与主控端解析完全对应。ESP32 侧 main.cpp 的蓝牙写特征回调L786-L795按如下规则解码字节含义主控端解码main.cppdata[0]帧头0xAA长度必须为 4否则丢弃data[1]摇杆 X转向target.yawSpeedCmd -(data[1]/100.0f - 1) * 1.5fdata[2]摇杆 Y前进target.speedCmd (data[2]/100.0f - 1) * 1.0fdata[3]滑块腿长target.legLength (data[3]/200.0f) * 0.02f 0.07f约 0.07~0.09 m另外0xAB单字节帧表示触发起立App 在配置菜单中选择了发送站立指令后会根据当前模式经 UDP 或蓝牙发出0xABMainActivity.java L56-L62主控端则创建Ctrl_StandupPrepareTask任务执行站立流程main.cpp L792-L795。3.3 NanoPI 侧的 UDP↔蓝牙桥在图传模式下UDP 数据并不直接到达 ESP32而是先到达 NanoPI 上运行的 ctrl-proxy.py。该脚本绑定0.0.0.0:5000创建 UDP 服务器L27-L33收到 App 数据后进入遥控数据转发模式is_proxy_mode True并顺带service mjpg-ffserver start启动视频推流L112-L115通过 bleak 扫描并连接名为BalanceBot的下位机L141-L160把 UDP 队列里的帧写入 ESP32 的 TX 特征4c9a0002-...并通过start_notify订阅其 RX 特征4c9a0003-...把下行数据经 UDP 转发回 AppL124-L127超过 5 秒未收到 UDP 消息则退出转发模式并停止推流服务L118-L121实现人不在、视频关的省电逻辑。因此图传模式下整条链路为App(UDP:15000) → NanoPI(UDP:5000) → BLE → ESP32视频链路为App(WebView/HTTP) ← ffserver:8090 ← ffmpeg ← ov5640 摄像头。四、蓝牙配网方案BLE 文本协议驱动图传入网文档定义蓝牙配网指本程序先通过蓝牙直接连接到图传系统向其发送网络信息使其连接到指定的 WiFi 网络此后即可通过网络连接到图传系统整个过程自动完成。4.1 双 GATT 客户端与两组 UUIDMainActivity中实际创建了两个BLE 客户端实例Bluetooth.java 封装标准 GATT 客户端实例目标设备蓝牙名Service UUID写特征App→设备Notify 特征设备→AppbtCtrlESP32 主控BalanceBot4c9a0001-fb2e-432e-92ec-c6f5316b46894c9a0002-...4c9a0003-...btUpperNanoPI 图传NanoPI4c9a0011-fb2e-432e-92ec-c6f5316b46894c9a0013-...4c9a0012-...这三组 UUID 与固件端定义一一对应ESP32 侧见 main.cpp L25-L28 的UUID_SERVICE/UUID_RX_CHARA/UUID_TX_CHARA与BLE_NAME BalanceBotNanoPI 侧见 ctrl-proxy.py L21-L24bless库创建的 GATT Servernotify 特征4c9a0012、write 特征4c9a0013。Bluetooth.java的实现细节值得借鉴连接成功后调用setPreferredPhy(PHY_LE_2M, ...)协商 2M PHYL64降低遥控链路时延服务发现后向00002902-...CCCD写入ENABLE_NOTIFICATION_VALUE开启订阅L94-L97首次扫描到设备后把 MAC 地址存入SharedPreferenceskey 为MAC 设备名L133-L135下次connectDevice直接按 MAC 连接而不再全量扫描L158-L162选择进行连接配置时会调用clearMacInfo()强制重新扫描MainActivity L77-L80连接断开后 1 秒自动重连L75-L80保证链路的自愈能力。4.2 配网协议一组约定的文本命令App 与 NanoPI 之间的 BLE 数据是 UTF-8 文本命令由btUpper的回调处理MainActivity.java L114-L185与 ctrl-proxy.py 的on_self_writeL228-L256严格对应方向命令触发与含义App → NanoPISCAN_WIFI请求扫描周边 WiFi配网模式下连接成功即发送L122-L124NanoPI → AppWIFI_LIST:名1\t名2...扫描结果App 弹出列表让用户选择L136-L154App → NanoPICONN_WIFI:SSID\t密码用户选定网络并输入密码后发送L148NanoPI → AppCONN_WIFI_OK/CONN_WIFI_ERRWiFi 连接结果反馈失败则 App 提示并重扫L155-L165App → NanoPIGET_IP配网成功后延时 1 秒请求对端 IPL157-L162NanoPI → AppSELF_IP:ip通过get_ip_address(wlan0)回报自身 IPctrl-proxy.py L233收到SELF_IP后App 执行收尾动作L166-L182wifiClient.setServerAddress(ip, 5000)设置 UDP 目标、ctrlView.setServerIP(ip)切换视频源、断开 BLE至此配网流程闭环遥控帧与视频流均走网络。此外 NanoPI 端还实现了SET_AP命令设置热点模式 SSID/密码ctrl-proxy.py L250-L255当前 App 版本未调用属于预留能力。非配网状态下App 连接NanoPI后直接发送GET_IP获取 IPL125-L128即可快速进入图传模式——这正是再次打开 App 无需重新配网的机制。五、主要文件清单与工程配置文档列出的关键文件如下已逐一与仓库核对文件职责balancebot.apk预编译安装包可直接安装MainActivity.java主 Activity创建各模块对象、处理用户菜单事件、10Hz 发送遥控帧Bluetooth.javaBLE GATT 客户端扫描、连接、MAC 缓存、特征读写与订阅WifiClient.javaUDP 客户端本地 15000 端口、阻塞接收线程CtrlView.java主视图重写自 WebView负责界面叠加绘制与触摸分发AndroidManifest.xml权限与 Activity 声明res/drawable摇杆底图、状态图标等图片资源streamview.htmlWebView 视频流页面工程层面的可考证信息app/build.gradle、gradle-wrapper.propertiescompileSdk 32、minSdk 26、targetSdk 32Java 8 语法级别Gradle 7.2Android Studio 对应 2021 年之后的版本即可打开依赖仅androidx.appcompat、material、constraintlayout三件套没有引入任何第三方蓝牙/网络库——BLE 用系统 GATT API网络用原生DatagramSocket这一点在阅读源码时容易高估其复杂度实际非常轻量。AndroidManifest.xml 的权限声明体现了对 Android 版本差异的处理与 MainActivity 中的运行时申请逻辑L214-L222配合Android 12API 31及以上BLUETOOTH_SCAN声明neverForLocationBLUETOOTH_CONNECTAPI 30 及以下传统BLUETOOTH/BLUETOOTH_ADMINmaxSdkVersion30蓝牙扫描所需的位置权限ACCESS_COARSE_LOCATION/ACCESS_FINE_LOCATION对应源码中 S 以下申请精确定位、Q 以下申请粗略定位的分支INTERNETusesCleartextTraffictrue视频流为明文 HTTPMainActivity声明为横屏screenOrientationlandscape界面即按横屏布局设计。六、使用说明继承原文档并补充给机器人上电等待图传系统启动完成约 1 min打开本程序点击左上角的配置按钮菜单包含四项切换为蓝牙模式、切换为图传模式、进行连接配置、发送站立指令见 MainActivity.java L53不使用图传点选切换为蓝牙模式等待连接成功App 扫描并连接名为BalanceBot的 ESP32 设备使用图传点选切换为图传模式然后再次点击配置按钮选择进行连接配置按要求选择网络并输入密码等待连接成功即 4.2 节的完整配网流程左上角配置按钮由灰色变亮即表示连接成功蓝牙模式亮蓝牙图标、图传模式亮视频图标此时即可使用摇杆控制机器人。补充两点源码可证实的使用细节模式持久化所选模式会写入SharedPreferences的useVideoMode键L100下次启动 App 时自动按上次模式连接对应设备L260-L266无需重复选择站立指令机器人趴倒后可在菜单中选择发送站立指令发送0xAB帧触发主控的站立准备任务摇杆 X 轴控制转向主控端按 1.5 倍增益换算Y 轴控制前进后退底部滑块实时调节腿部长度映射为 0.07~0.09 m 的腿长目标值松开摇杆即停止。七、小结可复用的设计要点从这份实现中可以提炼出对类似机器人远程调试 App项目有参考价值的几条设计决策显示零成本化把 MJPG 推流端点设计成标准 HTTP 资源App 用 WebView 直接当视频容器HTML 只写 60 行以内的代码Native 层不碰任何视频解码单帧定长协议遥控数据压缩为 1 字节帧头 3 字节量化参数(值1)*100的无符号化技巧让 float 区间 [-1,1] 落入一个字节10Hz 发送UDP 与 BLE 两条通道共用同一帧格式主控端解析逻辑零分支差异配网即协议BLE 通道被复用为带外管理通道用SCAN_WIFI / CONN_WIFI / GET_IP这类简单文本命令完成入网与 IP 发现避免了 App 与图传系统之间需要人工输入 IP 的繁琐步骤链路自愈BLE 断线 1 秒重连、HTML 页 3 秒心跳刷新视频源、UDP 5 秒超时自动退出转发模式三处自愈逻辑共同降低了现场调试成本。以上全部行为均可在仓库中按文件路径逐一验证App 端四个 Java 源文件 一个 HTML 页面Linux 端一个 Python 脚本固件端main.cpp中的蓝牙解码回调共同构成了这套轮腿机器人的完整远程操控链路。赞分享机器人嵌入式硬件开发移动开发【免费下载链接】foc-wheel-legged-robotOpen source materials for a novel structured legged robot, including mechanical design, electronic design, algorithm simulation, and software development. | 一个新型结构的轮腿机器人开源资料包含机械设计、电子设计、算法仿真、软件开发等材料项目地址https://gitcode.com/gh_mirrors/fo/foc-wheel-legged-robot点击查看免费下载相关推荐FOC 轮腿机器人 Android 遥控 App触摸遥控、MJPG 图传显示与蓝牙自动配网实现解析FOC 轮腿机器人 Android 遥控 App触摸遥控、MJPG 图传显示与蓝牙自动配网实现解析 本文围绕 android/README.md 讲解 foc机器人嵌入式硬件开发移动开发QGroundControl虚拟摇杆与遥控器配置多种控制方式详解QGroundControl虚拟摇杆与遥控器配置多种控制方式详解 QGroundControl作为跨平台无人机地面控制站提供了多种灵活的控制方式让用户能够无人机智能硬件高级应用使用cross-de-zh-roberta-sentence-transformer构建智能客服系统高级应用使用cross de zh roberta sentence transformer构建智能客服系统 在全球化时代企业需要跨越语言障碍提供高效服务。创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考