Управление роботом с мобильного устройства распадается на несколько принципиально разных задач: телеоперация в реальном времени (джойстик для колёсной платформы или манипулятора), мониторинг состояния (заряд, температура, статус задачи), программирование миссий (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 день и предложим оптимальное решение.







