# Flutter + Jetson + ROS 2: Optimizing High-Frequency Robot Telemetry

> Source: <https://dev.to/vmodal_ai/flutter-jetson-ros-2-optimizing-high-frequency-robot-telemetry-2hkn>
> Published: 2026-10-06 17:08:52+00:00

This tutorial focuses on practical performance engineering for Flutter applications connected to smart glasses, NVIDIA Jetson, ROS 2, and Physical AI systems.

Start by deciding which data needs real-time treatment and which data can be delayed. A useful mobile target is roughly 16 ms per frame for a 60 Hz display. High-frequency robot telemetry should not automatically trigger a full widget-tree rebuild.

Use separate budgets for:

A scalable design is:

```
Smart Glasses / Robot
        |
        v
Native Android / Jetson / ROS 2
        |
        v
Transport Layer
(WebSocket / MQTT / gRPC / REST)
        |
        v
Flutter Repository
        |
        v
State Controller
        |
        v
Lightweight Widgets
```

Keep transport, state, and presentation separate.

```
class RobotTelemetry {
  final double battery;
  final double cpu;
  final double temperature;

  const RobotTelemetry({
    required this.battery,
    required this.cpu,
    required this.temperature,
  });
}
```

The UI should consume application-level models instead of raw ROS 2 or wearable messages.

Avoid putting all telemetry into one large `setState()`.

Prefer independently updating sections:

```
Column(
  children: [
    BatteryCard(),
    CpuCard(),
    TemperatureCard(),
    CameraPreview(),
    RobotLogPanel(),
  ],
)
```

Use granular state subscriptions so a battery change does not rebuild the camera preview.

If ROS 2 or a wearable SDK produces 100 messages per second, the UI normally does not need 100 complete rebuilds per second.

Keep the newest value and publish it to the UI at a controlled interval:

```
Timer? _uiTimer;
RobotTelemetry? _latest;

void onTelemetry(RobotTelemetry value) {
  _latest = value;
}

void startUiUpdates() {
  _uiTimer = Timer.periodic(
    const Duration(milliseconds: 100),
    (_) {
      final value = _latest;
      if (value != null) {
        updateVisibleTelemetry(value);
      }
    },
  );
}
```

This separates high-frequency acquisition from UI refresh.

For smart-glasses cameras and robot vision, an old frame can be less useful than the newest frame.

Prefer a bounded pipeline:

``` php
Frame -> processing
          |
newer frame replaces waiting frame
```

rather than allowing an unlimited queue to grow.

Large JSON decoding, image transformations, filtering, and other CPU-heavy Dart work can cause frame drops.

For suitable CPU-bound work:

```
final result = await compute(processPayload, payload);
```

For hardware-specific or very expensive processing, move the work to native Android, Jetson, ROS 2, or another dedicated service.

Do not send every raw camera frame through a Flutter platform channel.

Prefer:

``` php
Camera
  -> Native processing
  -> filtering/compression
  -> selected result
  -> Flutter
```

For many operator applications, detections, metadata, status, or a preview frame are more useful than raw sensor data.

A strong robotics architecture is:

```
ROS 2 Sensors
     |
     v
ROS 2 / Isaac ROS Processing
     |
     v
Jetson AI / Control
     |
     v
WebSocket / MQTT / gRPC
     |
     v
Flutter
```

Flutter can receive compact state such as:

```
{
  "robot_id": "r01",
  "battery": 82.5,
  "speed": 1.2,
  "obstacles": 3,
  "ai_state": "tracking"
}
```

instead of every low-level sensor sample.

Combine related values into snapshots instead of sending many tiny messages:

```
{
  "timestamp": 1720000000,
  "battery": 82.5,
  "cpu": 61.2,
  "temperature": 57.0,
  "pose": {
    "x": 1.2,
    "y": 3.4,
    "yaw": 0.8
  }
}
```

Batching reduces message overhead and makes Flutter state updates simpler.

Do not render every raw point-cloud or sensor message directly in Flutter.

Use the robotics side to:

Then render the simplified result in Flutter.

AI models can generate frequent inference results. Flutter usually needs only useful, current results.

Filter by confidence:

``` js
final visible = detections
    .where((d) => d.confidence >= 0.60)
    .toList();
```

Also consider duplicate suppression, latest-result caching, and rate limiting before updating the UI.

For camera and AI screens:

A 720p preview may be more appropriate than transferring a 4K frame when the UI displays only a small preview.

For long detection, diagnostic, or telemetry lists:

```
ListView.builder(
  itemCount: detections.length,
  itemBuilder: (context, index) {
    return DetectionTile(
      detection: detections[index],
    );
  },
)
```

Avoid constructing every list item when only a small portion is visible.

Do not judge production performance only from debug mode.

Measure:

Trace the complete path:

``` php
Sensor
 -> processing
 -> transport
 -> Flutter state
 -> widget build
 -> rendered frame
```

A small diagnostics model can expose performance problems:

```
class PerformanceStats {
  int messagesReceived = 0;
  int uiUpdates = 0;
  int framesDropped = 0;
  int commandsSent = 0;
}
```

If a stream receives 200 messages/sec but the screen needs only 10 updates/sec, the difference becomes visible immediately.

Performance optimization must never compromise safety.

Commands should use:

Example:

```
Flutter
  |
  | command + sequence ID
  v
Jetson
  |
  | acknowledgement
  v
Flutter
```

The robot must have its own safe-state behavior if Flutter or the network disappears.

For Meta or Google smart-glasses companion apps, filter wearable events before forwarding them to Flutter:

``` php
Wearable event
   |
   v
Native SDK
   |
   +--> filtering
   +--> throttling
   +--> aggregation
   |
   v
Flutter
```

For camera and audio workloads, native APIs should handle device-specific processing where practical.

For remote robots, use:

Separate traffic into:

```
HIGH: commands, emergency state, safety
MEDIUM: telemetry, AI detections
LOW: logs, debug metrics
```

Low-priority logging should never block control messages.

```
class TelemetryController {
  RobotTelemetry? _latest;
  Timer? _timer;

  void receive(RobotTelemetry data) {
    _latest = data;
  }

  void start(void Function(RobotTelemetry) publish) {
    _timer = Timer.periodic(
      const Duration(milliseconds: 100),
      (_) {
        final value = _latest;
        if (value != null) publish(value);
      },
    );
  }

  void dispose() {
    _timer?.cancel();
  }
}
```

This is useful when acquisition is much faster than the desired UI update rate.

```
                Smart Glasses
                     |
              Native Android SDK
                     |
                     v
ROS 2 <------> Jetson / AI <------> NVIDIA Models
  |                  |
  |                  v
  +------------> Gateway
                    |
             WebSocket/MQTT/gRPC
                    |
                    v
             Flutter Repository
                    |
             Telemetry Controller
                    |
        +-----------+-----------+
        |           |           |
     Status       Camera      AI UI
        |           |           |
        +-----------+-----------+
                    |
              Operator UI
```

Flutter should focus on interaction, visualization, navigation, and operator controls. Jetson/ROS 2 should handle sensor processing, AI inference, and real-time robotics. Native wearable SDKs should handle platform-specific device access.

The largest performance gains in Flutter robotics and smart-glasses applications usually come from controlling the data pipeline rather than micro-optimizing individual widgets.

Use this sequence:

```
Acquire
   ↓
Process
   ↓
Filter
   ↓
Throttle
   ↓
Transport
   ↓
State
   ↓
Render
```

Do expensive work close to the hardware, send only useful information to Flutter, and render at a rate meaningful to the operator.

Website: [www.v-modal.com](http://www.v-modal.com)

SDK Flutter: [https://github.com/v-modal/vmodal_sdk_flutter](https://github.com/v-modal/vmodal_sdk_flutter)

SDK Android: [https://github.com/v-modal/vmodal_sdk_android](https://github.com/v-modal/vmodal_sdk_android)

Discord: [https://discord.gg/K72z28KUx](https://discord.gg/K72z28KUx)
