Journal Article

船舶中央控制系统:基于Android的实时摇杆遥控方案

介绍基于Android的船舶中央控制系统,通过WebSocket实现低延迟摇杆远程控制,集成了高德地图导航、二维码扫码连接、双通道推进器控制和安全状态机管理等功能。

11 min2 views

船舶中央控制系统:基于Android的实时摇杆遥控方案

项目地址:Gitee - CenterShipController

项目概述

CenterShipController 是一款专为船舶远程控制设计的 Android 应用,通过 WebSocket 协议建立可靠的通信链路,实现对船舶设备的实时监控和精确控制。

系统采用主从架构,Android 端作为控制终端(遥控器),通过摇杆、地图导航、设备状态监控等核心功能,实现对船舶推进系统的远程操控。


功能架构

1. 摇杆控制系统

信号采集与预处理

用户通过屏幕虚拟摇杆操作,系统实时捕获触摸点的像素坐标:

java
// 坐标系转换 - 以摇杆中心为原点
float dx = touchX - centerX;
float dy = touchY - centerY;

// 极坐标计算
float distance = (float) Math.sqrt(dx * dx + dy * dy);
float angle = (float) Math.atan2(dy, dx);

死区与边缘缓冲

区域半径范围处理方式
中心死区0~10%视为无操作,避免抖动
正常区域10%~95%比例映射为推力
边缘缓冲95%~100%限制数值突变
java
// 死区处理
private static final float CENTER_DEAD_ZONE = 0.05f;  // 5%死区
private static final float EDGE_BUFFER_ZONE = 0.05f;  // 5%边缘缓冲

if (distance < CENTER_DEAD_ZONE) {
    return ControlCommand.createZeroCommand();  // 死区内返回零指令
}

标准化输出

将摇杆位移映射到 [-1, 1] 范围:

  • X 轴(水平):左偏为负,右偏为正
  • Y 轴(垂直):后拉为负,前推为正

2. 高性能通信架构

无锁设计

使用 AtomicReference 替代传统锁,减少线程竞争:

java
// 原子引用存储最新输入和指令
private final AtomicReference<JoystickInput> latestInput = new AtomicReference<>();
private final AtomicReference<ControlCommand> latestCommand = 
    new AtomicReference<>(ControlCommand.createZeroCommand());

线程模型

code
触摸输入 → 高优先级控制线程 → 命令生成 → WebSocket 发送
                     ↓
            振动反馈执行器(独立线程池)
java
// 高优先级控制线程
controllerThread = new HandlerThread("JoystickController", Thread.MAX_PRIORITY);
controllerThread.start();
controllerHandler = new Handler(controllerThread.getLooper());

// 独立振动线程池,避免阻塞主线程
private final ExecutorService vibrationExecutor = Executors.newSingleThreadExecutor();

WebSocket 心跳机制

保持长连接稳定性,通过 MainDeviceSocket 管理实时数据交换:

java
// WebSocket 连接管理
public class MainDeviceSocket {
    private WebSocket webSocket;
    private final long HEARTBEAT_INTERVAL = 10000; // 10秒心跳
    
    private void startHeartbeat() {
        heartbeatTimer.scheduleAtFixedRate(() -> {
            if (isConnected()) {
                sendPing();
            }
        }, 0, HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
    }
}

3. 控制命令生成时序

完整流程

code
用户触摸 → 坐标采集 → 极坐标转换 → 死区过滤 
    → 标准化输出 → 通道推力计算 → 安全状态机 
    → JSON序列化 → WebSocket发送

安全状态机

code
                 ┌─────────┐
     超时500ms   │  EMERGENCY │ ← 紧急停止
    ┌───────────→│   STOP    │
    │            └─────────┘
    │
┌───────┐    新方向    ┌──────────┐   100ms后   ┌─────────┐
│ 当前   │────────────→│ DIR_CHANGE │────────────→│ 新方向   │
│ 方向   │             │ (停止延时) │             │ 运行    │
└───────┘             └──────────┘             └─────────┘
java
// 方向切换保护
private static final long DIRECTION_CHANGE_DELAY = 150; // 150ms停止延时

if (directionChanged) {
    // 立即关闭电机使能
    sendCommand(ControlCommand.createStopCommand());
    // 延迟后切换方向
    controllerHandler.postDelayed(() -> {
        switchDirection();
        sendCommand(newCommand);
    }, DIRECTION_CHANGE_DELAY);
}

JSON 指令格式

json
{
  "SHIPMOTRO": {
    "CH1": 75,    // 左推进器推力 (0-100)
    "DIR1": 1,    // 左推进器方向 (0=反转, 1=正转)
    "EN1": 0,     // 左推进器使能 (0=启用, 1=禁用)
    "CH2": 60,    // 右推进器推力 (0-100)
    "DIR2": 0,    // 右推进器方向
    "EN2": 0      // 右推进器使能
  }
}

4. 地图与定位

集成高德地图 SDK,提供实时位置显示和导航:

  • 实时定位:GPS 轨迹追踪
  • 地图交互:缩放、平移、标记
  • 路径规划:导航路线显示

5. 设备连接

通过 ZXing 二维码扫描快速建立连接:

code
App 扫描二维码 → 解析设备信息(IP/Port/ID) → WebSocket 连接 → 状态显示

连接状态实时反馈:

  • 绿色指示灯:已连接
  • 显示设备 ID、电池电量、工作状态

技术栈

技术
语言Java
UIAndroid原生 + 自定义View
地图高德地图SDK
通信WebSocket (OkHttp3)
序列化Gson
扫码ZXing
权限EasyPermissions
构建Gradle

性能优化

1. 命令缓存

预计算常用指令,减少重复序列化开销:

java
private final Map<String, ControlCommand> commandCache = new ConcurrentHashMap<>();
private final Map<String, String> jsonCache = new ConcurrentHashMap<>();

2. 性能监控

内置性能监控器,实时追踪各环节延迟:

java
private final PerformanceMonitor inputMonitor = new PerformanceMonitor("输入处理");
private final PerformanceMonitor filterMonitor = new PerformanceMonitor("滤波处理");
private final PerformanceMonitor commandGenMonitor = new PerformanceMonitor("命令生成");
private final PerformanceMonitor sendMonitor = new PerformanceMonitor("命令发送");
private final PerformanceMonitor fullPathMonitor = new PerformanceMonitor("全路径延迟");

3. 发送频率控制

每 200ms 更新并发送控制命令,平衡实时性与网络开销。


安装要求

项目要求
系统版本Android 6.0 (API 23) 或更高
依赖高德地图SDK、ZXing
硬件摄像头、网络连接

项目结构

code
centershipcontroller/
├── Activity/
│   ├── QR_codeScannerActivity.java   # 二维码扫码
│   ├── SettingsActivity.java         # 设置页
│   └── OperationSettingsActivity.java # 操作设置
├── Component/
│   ├── DeviceInfoCard.java           # 设备信息卡片
│   └── CustomDialog.java            # 自定义对话框
├── Socket/
│   ├── MainDeviceSocket.java         # WebSocket主通信
│   └── ShipDevicesSocket.java        # 设备Socket管理
├── Utils/
│   ├── JoySticksDecoder.java        # 摇杆解码器(核心)
│   ├── WebSocketManager.java        # WebSocket管理器
│   ├── QRCodeProcessor.java         # 二维码处理
│   └── UserSettings.java            # 用户设置
├── Views/
│   ├── JoystickView.java            # 自定义摇杆视图
│   └── QRCodeScannerView.java       # 扫码视图
└── MainActivity.java                # 主界面

总结

CenterShipController 是一个完整的嵌入式船舶遥控系统客户端实现,核心亮点:

  • 高性能:无锁设计 + 原子引用 + 独立线程池
  • 高可靠:WebSocket 心跳 + 安全状态机 + 信号丢失检测
  • 低延迟:预计算缓存 + 性能监控 + 滤波优化
  • 模块化:清晰的代码分层,便于维护和扩展

该方案不仅适用于船舶控制,也可作为其他遥控系统的参考架构。