Керування роботом з мобільного пристрою поділяється на кілька принципово різних завдань: телеоперація в реальному часі (джойстик для колісної платформи або маніпулятора), моніторинг стану (заряд, температура, статус завдання), програмування місій (waypoints, pick-and-place послідовності), відеотрансляція з камер. Типова проблема — висока затримка керування та нестабільне відео, особливо при роботі через громадські мережі. Ми займаємося розробкою мобільних додатків для робототехніки понад 5 років — у нашому портфелі проекти з Boston Dynamics Spot, Universal Robots UR-серії та власних платформах на ROS 2. Економія часу на налагодження завдяки готовим модулям сягає 30%, а вартість підтримки знижується на 40% за рахунок використання перевірених архітектурних рішень. Оцінимо ваш проект за 1 день, отримайте консультацію.
Як розробляється мобільний додаток для керування робототехнікою?
ROS 2 та rosbridge: стандарт у дослідницькій та промисловій робототехніці
ROS 2 (Robot Operating System) — де-факто стандарт в академічній і все більше в промисловій робототехніці (Universal Robots UR-серія, MiR мобільні платформи, Boston Dynamics Spot SDK). rosbridge_suite надає WebSocket API для взаємодії з ROS-топіками, сервісами та параметрами з будь-якої мови.
class RosbridgeClient { late WebSocketChannel _channel; final _topicStreams = <String, StreamController<dynamic>>{}; int _opId = 0; Future<void> connect(String url) async { _channel = WebSocketChannel.connect(Uri.parse(url)); _channel.stream.listen(_handleMessage); } // Підписка на ROS-топік Stream<T> subscribe<T>(String topic, String type, T Function(Map<String, dynamic>) fromJson) { final controller = StreamController<T>.broadcast(); _topicStreams[topic] = controller as StreamController<dynamic>; _channel.sink.add(jsonEncode({ 'op': 'subscribe', 'topic': topic, 'type': type, 'id': 'sub_${_opId++}', })); return controller.stream.map((data) => fromJson(data as Map<String, dynamic>)); } // Публікація в ROS-топік void publish(String topic, String type, Map<String, dynamic> message) { _channel.sink.add(jsonEncode({ 'op': 'publish', 'topic': topic, 'type': type, 'msg': message, })); } void _handleMessage(dynamic raw) { final msg = jsonDecode(raw as String) as Map<String, dynamic>; if (msg['op'] == 'publish') { final topic = msg['topic'] as String; _topicStreams[topic]?.add(msg['msg']); } } } Як ми забезпечуємо низьку затримку при телеоперації?
Керування колісною платформою через віртуальний джойстик публікує geometry_msgs/Twist у топік /cmd_vel. Критична вимога — latency. При затримці >200 мс керування стає некомфортним, >500 мс — небезпечним. WebRTC перевершує MJPEG за затримкою в 2–4 рази, що критично для телеоперації.
class TeleopController { final RosbridgeClient _rosbridge; Timer? _publishTimer; void startTeleop(Stream<Offset> joystickInput) { joystickInput.listen((offset) { _currentLinear = offset.dy * MAX_LINEAR_SPEED; // м/с _currentAngular = -offset.dx * MAX_ANGULAR_SPEED; // рад/с }); // Публікуємо Twist з фіксованою частотою 10 Гц _publishTimer = Timer.periodic(const Duration(milliseconds: 100), (_) { _rosbridge.publish('/cmd_vel', 'geometry_msgs/Twist', { 'linear': {'x': _currentLinear, 'y': 0.0, 'z': 0.0}, 'angular': {'x': 0.0, 'y': 0.0, 'z': _currentAngular}, }); }); } void stopTeleop() { _publishTimer?.cancel(); _rosbridge.publish('/cmd_vel', 'geometry_msgs/Twist', { 'linear': {'x': 0.0, 'y': 0.0, 'z': 0.0}, 'angular': {'x': 0.0, 'y': 0.0, 'z': 0.0}, }); } } Watchdog на роботі: якщо /cmd_vel не надходив 0.5 секунди — аварійна зупинка. Це стандартна практика для мобільних платформ. Втрата WiFi або перемикання мережі = робот зупиняється сам. Ми гарантуємо, що додаток коректно обробляє такі сценарії.
Відеотрансляція: MJPEG vs WebRTC
web_video_server — ROS-пакет, стримить топіки sensor_msgs/Image через HTTP MJPEG/h264. Для мобільного клієнта на Flutter:
Widget buildCameraView(String topic) { final url = 'http://$robotIp:8080/stream?topic=$topic&type=mjpeg&quality=70'; return MjpegStreamView(url: url); } Для latency <200 мс потрібен WebRTC — webrtc_ros пакет або Janus Gateway. WebRTC дає real-time відео з sub-100 мс затримкою через flutter_webrtc:
class RobotVideoCall { late RTCPeerConnection _peerConnection; Future<void> startStream() async { _peerConnection = await createPeerConnection({ 'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}], }); _peerConnection.onTrack = (RTCTrackEvent event) { if (event.track.kind == 'video') { _videoRenderer.srcObject = event.streams.first; } }; final offer = await _peerConnection.createOffer(); await _peerConnection.setLocalDescription(offer); _signalingChannel.send(offer.sdp); } } | Метод | Затримка (latency) | Якість | Складність інтеграції |
|---|---|---|---|
| MJPEG (HTTP) | 200–400 мс | Середнє (стиснення JPEG) | Низька (вбудований пакет) |
| WebRTC (UDP) | <100 мс | Високе (адаптивний бітрейт) | Середня (необхідний signalling) |
| Платформа | Переваги | Недоліки |
|---|---|---|
| Flutter | Висока швидкість розробки, єдина кодова база | Обмежена робота з нативними SDK |
| Нативний (Kotlin/Swift) | Повний доступ до API, краща продуктивність | Довше розробка, два коди |
Вибір методу відеотрансляції залежить від вимог: для картографування достатньо MJPEG, для телеоперації — тільки WebRTC. Наші інженери допоможуть підібрати оптимальне рішення.
Навігація та waypoints
Для автономної навігації (ROS Navigation Stack, Nav2) — відправлення цільової точки через geometry_msgs/PoseStamped у /move_base_simple/goal (ROS 1) або action-сервер /navigate_to_pose (Nav2 в ROS 2):
Future<void> navigateTo(double x, double y, double yaw) async { final quaternion = yawToQuaternion(yaw); _rosbridge.publish('/goal_pose', 'geometry_msgs/PoseStamped', { 'header': { 'frame_id': 'map', 'stamp': {'sec': DateTime.now().millisecondsSinceEpoch ~/ 1000, 'nanosec': 0}, }, 'pose': { 'position': {'x': x, 'y': y, 'z': 0.0}, 'orientation': quaternion, }, }); } Map<String, double> yawToQuaternion(double yaw) { return { 'x': 0.0, 'y': 0.0, 'z': sin(yaw / 2), 'w': cos(yaw / 2), }; } Відображення карти — nav_msgs/OccupancyGrid з топіка /map. Растрова карта (uint8 array) конвертується в PNG і рендериться через flutter_map або кастомний CustomPainter.
Що входить у розробку мобільного додатку для робота?
- Аналітика та проектування архітектури — схема взаємодії, вибір стека (Flutter vs native).
- Розробка UI/UX — джойстик, карта, відео, панель моніторингу.
- Інтеграція з ROS 2 (rosbridge) або пропрієтарним SDK (Spot SDK, UR RTDE, Doosan, Kuka).
- Реалізація телеоперації (Twist), відеотрансляції (MJPEG/WebRTC), навігації (waypoints, action).
- Тестування на реальному роботі — польові випробування з вимірюванням latency та надійності.
- Навчання операторів — 2–3 сесії.
- Підтримка після запуску — 1 місяць гарантійного супроводу.
SDK пропрієтарних роботів
Boston Dynamics Spot — Spot SDK (Python + gRPC, мобільний клієнт через REST-обгортку). Universal Robots — UR RTDE (Real-Time Data Exchange) для телеметрії, URScript через сокет для команд. Doosan, Kuka — своїх SDK з REST API або Modbus TCP.
Чому варто замовити у нас?
У нас понад 5 років досвіду в робототехнічних проектах, понад 30 реалізованих рішень — від навчальних платформ до промислових маніпуляторів. Сертифіковані інженери володіють Swift, Kotlin, Flutter та Dart. Впроваджуємо найкращі практики: code signing, push notifications (APNs/FCM), deep linking (Universal Links). Гарантуємо дотримання App Store Review Guidelines та Google Play Policy. Зв'яжіться з нами — ми оцінимо ваш проект за 1 день і запропонуємо оптимальне рішення.







