Robot Operating System (ROS) is a widely used open-source framework for building robotic applications, offering navigation, manipulation, and sensor integration tools.
Integrating ROS with mobile platforms like Flutter enables real-time monitoring, control, and data visualization, enhancing the flexibility of robotics in applications such as industrial automation and research.
However, existing Flutter packages for ROS face challenges, including outdated SDK compatibility, incomplete features, poor documentation, and limited maintenance, hindering their reliability and scalability.
Addressing these issues through modern approaches like WebSocket-based communication can unlock the full potential of ROS in mobile app development.
Available Flutter Packages for ROS
-
dartros
Overview of dartros
The Dartros package is a Dart-based ROS client library inspired by C++ and Node.js implementations. It enables ROS operations like connecting to a ROS master, publishing/subscribing to topics, and generating custom message types for inter-node communication.
Features of dartros
- Publish/Subscribe (TCP): Reliable topic communication with standard messages (std_msgs, sensor_msgs).
- Services: Handles client-server interactions between nodes.
- Message Generation: Supports custom ROS message creation via the gendart package.
- ROS Master Connection: Compatible with both local and remote masters.
Advantages of dartros
- Simplifies ROS integration in Dart/Flutter apps.
- Pre-published message libraries for easy dependency management.
- Supports TCP-based communication for reliability.
Limitations of dartros
- SDK Compatibility: Limited to Dart SDK versions 2.12.0–3.4.0, incompatible with the latest versions.
- Documentation Gaps: Minimal API docs requiring reliance on examples.
- Platform and Maintenance: Lacks platform support testing and is no longer actively maintained.
- Setup Complexity: Custom message generation depends on the external setup of the Gendart package.
Implementation of dartros
1. Add Dependency
Include dartros in your pubspec.yaml file.
dependencies:
dartros: ^0.2.1
2. Code Snippet
// Connect to ROS and initialize publisher and subscriber
Future<void> _connectToROS() async {
// Connect to ROS master
_ros = await Ros.create();
await _ros.connect(‘ws://localhost:9090’); // Replace with your ROS master URI
// Create a publisher for a topic
_publisher = await _ros.advertise(‘/chatter’, ‘std_msgs/String’);
// Create a subscriber for a topic
_subscriber = await _ros.subscribe(‘/chatter’, ‘std_msgs/String’, _messageCallback);
}
// Callback for handling incoming messages
void _messageCallback(Message message) {
print(‘Received message: ${message.data}’);
}
// Function to publish messages
Future<void> _publishMessage() async {
String message = ‘Hello, ROS!’;
await _publisher.publish(StringMessage(data: message));
print(‘Message published: $message’);
}
Explanation
- Connect to ROS Master
Establish a WebSocket connection to the ROS master using its IP address (e.g., ws://<ROS_MASTER_IP>:9090). - Create a ROS Node
Initialize a ROS node instance to manage communication with the ROS master. - Define Topics
Specify the topic names and their message types (e.g., /chatter with std_msgs/String). - Publish Messages
Use a Publisher instance to send messages to a specified topic. - Subscribe to Messages
Use a Subscriber instance to listen for messages on a topic and handle them via a callback function.
-
ros_nodes
Overview of ros_nodes
- ros_nodes is a Dart package designed for direct ROS node implementation.
- It supports creating ROS nodes in Dart and enabling topic publishing and subscription.
Features of ros_nodes
- Direct node creation and connection to ROS master.
- Supports publishing and subscribing to topics.
Limitations of ros_nodes
- Limited support for complex message types and services.
- No native WebSocket or ROSBridge integration, restricting its usage in environments where direct TCP communication is not feasible.
- Less mature compared to other ROS libraries, with limited community support.
- No Documentation is available, eventually increasing development time and difficulty for the developer
- Works only with very old Flutter SDK versions (upto 3.7.1), making it incompatible with our application
Implementation of ros_nodes
The following code is used to connect to the ros with your flutter app
After installation of ROS in your Linux, just follow these steps for the same execution
Step 1: Get the IP address of your VM (Virtual Machine) using ifconfig
Step 2: Add dependency in pubspec.yaml
dependencies:
ros_nodes:
git:
url: https://github.com/Sashiri/ros_nodes.git
Step 3: In RosConfig function update your (Local Machine) IP address
Step 4: Run the app and enter the IP address of VM in the textbox. A topic will be created
Code Snippet
void _connect() async {
final ipAddress = _ipController.text.trim();
if (ipAddress.isEmpty) {
_showMessage(‘Please enter a valid IP address.’);
return;
}
try {
final config = RosConfig(
“main”,
‘http://$ipAddress:11311/‘,
“192.168.0.106”,
60527,
);
final client = RosClient(config);
setState(() {
_rosClient = client;
_isConnected = true;
});
_showMessage(‘Connected to ROS Master at $ipAddress’);
StdMsgsString message = StdMsgsString();
message.data = “text”;
_topic = RosTopic(‘/feedbackq’, message);
await client.unregister(_topic!);
_publisher = await client.register(
_topic!,
publishInterval: const Duration(milliseconds: 1000),
);
// Auto-incrementing counter
int counter = 0;
Timer.periodic(
const Duration(milliseconds: 500),
(_) {
if (!_isConnected || _topic == null || _publisher == null) return;
counter += 1;
_topic!.msg.data = ‘Counter: $counter’;
_publisher!.publishData();
},
);
} catch (e) {
_showMessage(‘Failed to connect: $e’);
}
}
-
roslib
Overview of roslib
roslib is a Dart library that communicates with ROS nodes over WebSockets using the rosbridge protocol. Inspired by roslibjs, it implements a subset of features required for ROS communication, including topics, services, and parameters.
However, it is an incomplete library, lacking advanced features and compatibility with modern Dart versions.
Features of roslib
Core Components:
- ROS Connection: Manages WebSocket communication with ROS.
- Topic Object: Supports subscribing, unsubscribing, publishing, advertising, and unadvertising topics.
- Service Object: Facilitates service calls, advertisement, and unadvertisement.
- Request Object: Provides structured naming and typing for ROS requests.
- Param Object: Enables getting, setting, and deleting ROS parameters.
Missing Features of roslib
- Actionlib: Components like ActionClient, ActionListener, Goal, and SimpleActionServer are not implemented.
- TFClient: No support for TF data from tf2_web_republisher.
- URDF Support: Lacks functionality for handling URDF elements like models, joints, and materials.
- TCP Connections: No support for ROS communication over TCP.
Limitations of roslib
- Incomplete Implementation: Several critical features, such as Actionlib and TFClient, remain unimplemented.
- Dart SDK Incompatibility: Supports Dart <3.0.0, making it incompatible with modern Dart SDK versions (e.g., 3.6.0) and null safety.
- Static Analysis Issues: Fails due to outdated dependencies and unresolved constraints.
- Platform Support: Unable to detect supported platforms due to dependency resolution issues.
roslib is suitable for basic ROS-WebSocket communication but requires further development to be viable for modern applications.
Implementation of roslib
1. Add Dependency
Include dartros in your pubspec.yaml file.
dependencies:
flutter:
sdk: flutter
roslib: ^0.2.0
2. Code Snippet
// Initialize ROS connection
void _initializeRos() {
ros = Ros(url: ‘ws://localhost:9090’); // ROS WebSocket URL
ros.onOpen = () {
print(‘ROS WebSocket connection established’);
_subscribeToChatter();
_publishMessage();
};
ros.onClose = () {
print(‘ROS WebSocket connection closed’);
};
ros.connect();
}
// Subscribe to the chatter topic
void _subscribeToChatter() {
chatterTopic = Topic(ros, ‘/chatter’, ‘std_msgs/String’);
chatterTopic.subscribe((message) {
setState(() {
receivedMessage = message[‘data’] ?? ‘No data’;
});
});
}
// Publish a message to the chatter topic
void _publishMessage() {
Future.delayed(Duration(seconds: 1), () {
chatterTopic.publish({‘data’: ‘Hello from Flutter!’});
print(‘Published message: Hello from Flutter!’);
});
}
}
Explanation
- Install ROS: Ensure ROS is installed and run roscore in a terminal.
- Publish Test Message: Use rostopic pub to send a message to the /chatter topic.
- Set Up Flutter Project: Create a new Flutter project and add roslib as a dependency.
- Write Code: Replace lib/main.dart with the provided code.
- Run Flutter App: Connect to the ROS WebSocket and run the app.
- Test Communication: The app should display the message received from ROS, and you can check the /chatter topic using rostopic echo.
- Expected Output: The Flutter app will show the published message, and ROS should display the same message.
Comparative Analysis
Feature | dartros | ros_nodes | roslib |
Communication Protocol | WebSocket (ROSBridge) | Direct TCP | WebSocket (ROSBridge) |
Topic Publishing/Subscribing | ✅ | ✅ | ✅ |
Service Calls | ✅ | ❌ | ✅ |
ROS Node Creation | ❌ | ✅ | ❌ |
Custom Message Support | Limited | Limited | ❌ |
Actionlib Support | ❌ | ❌ | ❌ |
URDF Support | ❌ | ❌ | ❌ |
TFClient Support | ❌ | ❌ | ❌ |
WebSocket Integration | ✅ | ❌ | ✅ |
Community Support | Moderate | Low | Moderate |
Platform Support | Incomplete | Very Limited | Failed Detection |
Dart SDK Compatibility | 2.12.0–3.4.0 | < 2.19.1 | < 3.0.0 |
Documentation Quality | Minimal | None | Minimal |
Maintenance Status | No Active Maintenance | No Active Maintenance | No Active Maintenance |
The Solution: WebSocket and Rosbridge
WebSocket is a communication protocol that enables full-duplex interaction between clients and servers, making it ideal for real-time applications.
Rosbridge, a middleware layer for ROS, provides a JSON API that allows non-ROS systems to interact with ROS nodes seamlessly. Together, they offer a streamlined solution for connecting ROS to modern mobile applications.
Advantages of WebSocket and Rosbridge
-
Modern Dart/Flutter Compatibility
Unlike traditional ROS integration methods, WebSocket and rosbridge are compatible with contemporary Dart and Flutter frameworks. This eliminates the need to rely on outdated or unsupported libraries, ensuring smooth development and deployment.
-
Scalability and Flexibility
This approach supports many robotics applications, from small-scale automation to complex systems, without compromising performance. The flexible JSON-based communication makes it easy to adapt to various use cases and system requirements.
-
Eliminates Outdated Dependencies
By leveraging WebSocket and rosbridge, developers can bypass older, deprecated packages and instead use a modern, lightweight solution. This results in cleaner, more maintainable code and a future-proof application architecture.
Step-by-Step Guide to Using WebSocket and rosbridge
-
Setting Up rosbridge
- Install and configure rosbridge_suite on your ROS system.
- Launch the WebSocket server using roslaunch rosbridge_server rosbridge_websocket.launch.
This allows external applications, including Flutter, to communicate with ROS nodes via WebSocket.
-
Establishing WebSocket Communication
- Use the web_socket_channel package in Flutter to initiate a WebSocket connection.
- Connect to the ws://<ROS-IP>:9090 endpoint and handle errors and disconnections to ensure stability.
-
Publishing and Subscribing to Topics
- Send a JSON message to advertise and publish to ROS topics.
- Similarly, subscribe to topics by sending a JSON subscription message.
- This enables seamless data exchange between your Flutter app development and ROS.
-
Handling Custom Messages
- Define custom ROS message types in your ROS environment and ensure your Flutter app’s JSON structure matches these types.
- Use appropriate topic names and data formats to avoid communication errors.
-
Testing Communication
- Use ROS tools like rostopic echo to monitor message flow.
- Verify publishing with rostopic pub to ensure correct message formats and topic handling.
Conclusion
Integrating Flutter with ROS using WebSocket and rosbridge offers a modern, flexible, and scalable approach to building robotics applications.
Developers can achieve real-time data exchange and robust functionality by bypassing outdated dependencies and leveraging direct WebSocket communication.
This method empowers mobile applications to interface seamlessly with ROS, unlocking new possibilities in robotics and automation while maintaining compatibility with modern Flutter standards.
If you need further help with Flutter app development, you can contact us at [email protected]. We will schedule a free consultation session to explore how Xavor can assist you.