Skip to content

Commit 3f05538

Browse files
Add ROS 2 iOS App Tutorial using Swift (#206)
This PR adds a comprehensive tutorial on building an iOS application integrated with ROS 2 using the SwiftROS2 framework. - Added 'Building an iOS App for ROS 2 Integration' wiki entry. - Covers project setup, node configuration, and SwiftUI interface development. - Includes detailed explanations of DDS middleware and dependency packages. - Updated site navigation and Common Platforms index. --------- Co-authored-by: LiaoChiawen <121083315+LiaoChiawen@users.noreply.github.com> Co-authored-by: Nevin Valsaraj <nevin.valsaraj32@gmail.com>
1 parent 9789316 commit 3f05538

3 files changed

Lines changed: 257 additions & 0 deletions

File tree

_data/navigation.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ wiki:
106106
url: /wiki/common-platforms/ros2-navigation-for-clearpath-husky/
107107
- title: Hello Robot Stretch RE1
108108
url: /wiki/common-platforms/hello-robot
109+
- title: Building an iOS App for ROS 2 Integration
110+
url: /wiki/common-platforms/ros2-ios-app-with-swift/
109111
- title: Configure VS Code for ROS 2
110112
url: /wiki/common-platforms/configure-vscode-for-ros2/
111113
- title: Building ROS2 Custom Packages

wiki/common-platforms/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ We encourage contributions to further enhance the knowledge base in this section
1414
- **[Asctec UAV Setup Guide](/wiki/common-platforms/asctec-uav-setup-guide/)**
1515
A detailed tutorial for setting up the Asctec Pelican UAV for autonomous waypoint navigation using ROS. Covers configuring network settings, flashing firmware, and running the ROS package on the onboard Atomboard.
1616

17+
- **[Building an iOS App for ROS 2 Integration](/wiki/common-platforms/ros2-ios-app-with-swift/)**
18+
A step-by-step guide on building an iOS application integrated with ROS 2 using the SwiftROS2 framework, covering project setup, node configuration, and SwiftUI interface development.
19+
1720
- **[Building a Custom Drone for the DARPA Triage Challenge](/wiki/common-platforms/building-custom-drone-for-darpa-triage-challenge/)**
1821
A comprehensive guide to designing and building UAVs for disaster scenarios. Covers both modified commercial platforms and fully custom designs, including hardware selection, electrical integration, and software configuration.
1922

@@ -96,6 +99,11 @@ Here is a compiled list of external resources referenced in the subsections:
9699
- [Universal Robots ROS Driver](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver)
97100
- [MoveIt Setup for UR5e](http://moveit.ros.org/)
98101

102+
10. **ROS 2 iOS Integration**
103+
- [SwiftROS2 Framework](https://github.com/strapsai/swift-ros2)
104+
- [Fast RTPS Documentation](https://fast-dds.docs.eprosima.com/en/latest/)
105+
- [Apple SwiftUI Documentation](https://developer.apple.com/documentation/swiftui)
106+
99107
## Development Needs
100108
We seek contributions in the following areas:
101109
- Detailed guides for setting up and integrating additional platforms like Boston Dynamics robots or custom robotic arms.
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
---
2+
date: 2025-04-29
3+
title: Building an iOS App for ROS 2 Integration
4+
---
5+
6+
This document provides a detailed, step-by-step guide on building an iOS application integrated with ROS 2 using the SwiftROS2 framework. In this guide, you will learn how to set up the project, configure ROS 2 nodes, implement publishers and subscribers to exchange messages via DDS, and build a SwiftUI-based user interface for operating ROS 2 functionality. In addition, this guide offers an in-depth explanation of the dependency packages and how the DDS mechanism is implemented to support ROS 2 communication. This guide assumes you have a basic understanding of Swift and iOS development. By the end, you will be able to create and run an iOS app that seamlessly interacts with ROS 2 nodes.
7+
8+
The complete code can be found at <https://github.com/LiaoChiawen/ROS2iOSApp>.
9+
10+
## Table of Contents
11+
- [Introduction](#introduction)
12+
- [Background and Key Concepts](#background-and-key-concepts)
13+
- [Step-by-Step Tutorial: Building an iOS App for ROS 2](#step-by-step-tutorial-building-an-ios-app-for-ros-2)
14+
- [1. Project Setup and Dependencies](#1-project-setup-and-dependencies)
15+
- [2. Creating the ROS 2 Node](#2-creating-the-ros-2-node)
16+
- [3. Implementing Publishers and Subscribers](#3-implementing-publishers-and-subscribers)
17+
- [4. Building the User Interface](#4-building-the-user-interface)
18+
- [5. Running and Testing the App](#5-running-and-testing-the-app)
19+
- [Detailed Explanation of Dependencies](#detailed-explanation-of-dependencies)
20+
- [swift-ros2](#swift-ros2)
21+
- [FastRTPSSwift](#fastrtpsswift)
22+
- [ros2msg](#ros2msg)
23+
- [Understanding the DDS Mechanism](#understanding-the-dds-mechanism)
24+
- [Usage Instructions](#usage-instructions)
25+
- [Summary](#summary)
26+
- [See Also](#see-also)
27+
- [Further Reading](#further-reading)
28+
- [References](#references)
29+
30+
## Introduction
31+
This tutorial explains how to build an iOS app that leverages ROS 2 capabilities using the SwiftROS2 framework. In this guide you will learn to initialize a ROS 2 node, set up publishers and subscribers via a DDS-based system, and construct a simple user interface with SwiftUI to operate core functionalities including initialization, message publishing, and node shutdown.
32+
33+
## Background and Key Concepts
34+
Before diving into the code, it is useful to understand these key concepts:
35+
- **ROS 2 (Robot Operating System 2):** A set of libraries and tools for building robot applications, which employs nodes, topics, and messaging to facilitate robust communication.
36+
- **DDS (Data Distribution Service):** A middleware protocol used in ROS 2 for real-time, scalable, and high-performance data exchange. It allows configuration of Quality of Service (QoS) parameters such as reliability and latency.
37+
- **Nodes:** The computational executables in ROS 2 that handle processing and communication.
38+
- **Publishers and Subscribers:** Mechanisms for sending (publishing) and receiving (subscribing) messages across nodes.
39+
- **SwiftROS2:** A simulated Swift library that provides interfaces to create ROS 2 nodes, publishers, and subscribers.
40+
- **iOS Development using SwiftUI:** SwiftUI is utilized for building modern, responsive user interfaces on iOS.
41+
42+
## Step-by-Step Tutorial: Building an iOS App for ROS 2
43+
44+
### 1. Project Setup and Dependencies
45+
1. **Clone the Repository:**
46+
Begin by cloning the codebase. Your repository key directories are:
47+
- `/ROS2iOS`: Contains the main source code.
48+
- `/ROS2iOSAppTests`: Holds unit tests.
49+
- `/Preview Content`: Contains sample packages and resources.
50+
51+
2. **Install Dependencies:**
52+
This project uses Swift Package Manager. Open your Xcode workspace (e.g. `ROS2iOS.xcodeproj`) and ensure the following packages are correctly resolved:
53+
- [swift-ros2](https://github.com/LiaoChiawen/swift-ros2)
54+
- [FastRTPSSwift](https://github.com/kabirkedia/FastRTPSSwift)
55+
- [ros2msg](https://github.com/LiaoChiawen/ros2msg)
56+
57+
Verify that your `Package.resolved` file lists the correct versions.
58+
59+
3. **Configure Xcode:**
60+
In Xcode, set the deployment target to iOS 17.0 and ensure proper code signing configurations.
61+
62+
### 2. Creating the ROS 2 Node
63+
The heart of the app is the ROS 2 node. The `CentralNode` class encapsulates ROS 2 functionalities including initialization and resource management.
64+
65+
- **Initialization:**
66+
In `ContentView.swift`, the `initialize()` function performs the following:
67+
- Retrieves the device IP using `getWiFiIPv4Address()`.
68+
- Creates a new `CentralNode` instance with a domain ID and IP address.
69+
- Calls asynchronous initialization on the node and associated publishers.
70+
71+
```swift
72+
// Example snippet from ContentView.swift:
73+
func initialize(){
74+
Task {
75+
configViewIP = getWiFiIPv4Address() ?? "127.0.0.1"
76+
observableCentralNode.centralNode = CentralNode(
77+
domainID: 0,
78+
ipAddress: configViewIP
79+
)
80+
81+
guard let cn = observableCentralNode.centralNode else {
82+
logger.error("Central Node is not ready/available. Cannot initialize.")
83+
return
84+
}
85+
await cn.initialize()
86+
await publisherModel.initialize(centralNode: cn)
87+
}
88+
}
89+
```
90+
91+
### 3. Implementing Publishers
92+
Communication between nodes is achieved by creating both publishers and subscribers.
93+
94+
- **Publishing:**
95+
The `PublisherModel.swift` file demonstrates setting up a publisher.
96+
97+
```swift
98+
// Excerpt from PublisherModel.swift:
99+
public func sendString() {
100+
guard let publisher = self.publisher else {
101+
logger.error("Publisher is not initialized.")
102+
return
103+
}
104+
105+
let ros2str = ROS2String()
106+
ros2str.data = "Hello World!"
107+
108+
let ddsMsg = DDSString(val: ros2str)
109+
110+
Task {
111+
await publisher.publish(ddsMsg)
112+
logger.info("Published \(ros2str.data)")
113+
}
114+
}
115+
```
116+
117+
118+
### 4. Building the User Interface
119+
The UI is built using SwiftUI and consists of three main buttons:
120+
- **Initialize:** Sets up the ROS 2 node and publishers.
121+
- **Publish Message:** Sends a test message.
122+
- **Destroy Node:** Tears down the node and cleans up.
123+
124+
```swift
125+
// Example snippet from ContentView.swift:
126+
var body: some View {
127+
VStack(spacing: 20) {
128+
Button("Initialize") {
129+
initialize()
130+
}
131+
.font(.headline)
132+
.frame(width: 140, height: 44)
133+
.padding()
134+
.background(Color.orange)
135+
.foregroundColor(.white)
136+
.cornerRadius(8)
137+
138+
Button("Publish Message") {
139+
publisherModel.sendString()
140+
}
141+
.font(.headline)
142+
.frame(width: 140, height: 44)
143+
.padding()
144+
.background(Color.blue)
145+
.foregroundColor(.white)
146+
.cornerRadius(8)
147+
148+
Button("Destroy Node") {
149+
destroyNode()
150+
}
151+
.font(.headline)
152+
.frame(width: 140, height: 44)
153+
.padding()
154+
.background(Color.red)
155+
.foregroundColor(.white)
156+
.cornerRadius(8)
157+
}
158+
.padding()
159+
}
160+
```
161+
162+
### 5. Running and Testing the App
163+
- **Build the Project:**
164+
Use Xcode to build the project ensuring that all dependencies are properly integrated.
165+
- **Run on Simulator or Device:**
166+
Launch the app on an iOS device or Simulator. Use the buttons to initialize the ROS 2 node, publish a message, and destroy the node.
167+
- **Testing:**
168+
Verify the functionality by checking Xcode console logs and running unit tests located in `/ROS2iOSAppTests`.
169+
170+
## Detailed Explanation of Dependencies
171+
172+
### swift-ros2
173+
- **Purpose:**
174+
Provides a high-level Swift interface to interact with ROS 2, allowing creation of nodes, publishers, and subscribers.
175+
- **Usage:**
176+
Classes such as `CentralNode` use this package to encapsulate ROS 2 operations and expose easy-to-use methods to initialize nodes and create communication channels.
177+
- **Implementation:**
178+
Utilizes Swift’s async/await for asynchronous operations and error-handling mechanisms for reliable integration with ROS 2 middleware.
179+
180+
### FastRTPSSwift
181+
- **Purpose:**
182+
Bridges ROS 2 DDS functionalities by leveraging the Fast RTPS (Real-Time Publish-Subscribe) protocol.
183+
- **Usage:**
184+
Manages low-level DDS operations such as registering writers (publishers) and readers (subscribers) and handles QoS settings (e.g., reliability, durability).
185+
- **Implementation:**
186+
Wraps the native C/C++ Fast RTPS libraries into Swift-friendly APIs, abstracting the complexity involved in direct DDS communications.
187+
188+
### ros2msg
189+
- **Purpose:**
190+
Defines message types and data structures used in ROS 2 communications.
191+
- **Usage:**
192+
Provides message models like `ROS2String` to package data and ensure proper serialization and deserialization using Swift’s Codable protocol.
193+
- **Implementation:**
194+
Structures messages in a way that aligns with ROS 2 standards, facilitating seamless interaction between different nodes and platforms.
195+
196+
## Understanding the DDS Mechanism
197+
DDS (Data Distribution Service) underpins the efficient and reliable exchange of data between ROS 2 nodes. Key points include:
198+
- **DDS Communication Model:**
199+
Uses a publish/subscribe model where publishers send messages to topics and subscribers receive them based on topic subscriptions.
200+
- **Quality of Service (QoS):**
201+
DDS allows customization of parameters (e.g., reliability, durability, latency) ensuring high-performance communication even in real-time applications.
202+
- **Fast RTPS Integration:**
203+
The FastRTPSSwift package bridges the Fast RTPS library with SwiftROS2, managing:
204+
- **Participant Creation:** The ROS 2 node (CentralNode) acts as a participant joining a DDS domain.
205+
- **Writer and Reader Registration:** Publishers (writers) and subscribers (readers) are registered with the DDS participant.
206+
- **Message Routing:** DDS middleware routes messages efficiently between registered writers and readers, applying QoS policies.
207+
- **Abstraction in SwiftROS2:**
208+
SwiftROS2 simplifies these complex operations into easy-to-use Swift classes and methods, allowing developers to focus on application logic rather than low-level protocol details.
209+
210+
## Usage Instructions
211+
1. **Clone and Open the Project:**
212+
Clone the repository and open `ROS2iOS.xcodeproj` with Xcode.
213+
2. **Resolve Dependencies:**
214+
Ensure that the Swift packages (swift-ros2, FastRTPSSwift, ros2msg) are downloaded and configured.
215+
3. **Build and Run:**
216+
Build the project and run the app on the desired iOS simulator or device.
217+
4. **Interact with the App:**
218+
- Tap **Initialize** to set up the ROS 2 node.
219+
- Tap **Publish Message** to send a test ROS 2 message.
220+
- Tap **Destroy Node** to gracefully shut down the ROS 2 node.
221+
5. **Review Logs:**
222+
Monitor the Xcode console for log messages confirming successful node initialization, message publishing, and node destruction.
223+
224+
## Summary
225+
This guide provided a comprehensive walkthrough for building an iOS app integrated with ROS 2:
226+
- Project setup, dependency resolution, and Xcode configuration.
227+
- Initializing a ROS 2 node with `CentralNode` and configuring communication via DDS.
228+
- Implementing publishers and subscribers to exchange messages.
229+
- Designing a user interface with SwiftUI and testing the functionality.
230+
- Detailed insights into the core dependency packages and DDS integration research.
231+
232+
## See Also
233+
- [ROS 2 Official Documentation](https://docs.ros.org/)
234+
- [Fast RTPS Documentation](https://fast-dds.docs.eprosima.com/en/latest/)
235+
- [Swift Package Manager Documentation](https://swift.org/package-manager/)
236+
- [SwiftUI Tutorials](https://developer.apple.com/tutorials/swiftui)
237+
238+
## Further Reading
239+
- Advanced DDS configuration and Quality of Service (QoS) settings.
240+
- Detailed tutorials on integrating C/C++ libraries with Swift.
241+
- Comprehensive studies of ROS 2 communication patterns and best practices.
242+
243+
## References
244+
1. Y. Hu, "swift-ros2 – ROS2-like node that supports subscription and publication of DDS messages in ROS2 message format," GitHub Repository, <https://github.com/strapsai/swift-ros2>.
245+
2. ROS Documentation, "Getting Started with ROS 2," available at <https://docs.ros.org/>.
246+
3. Fast RTPS Documentation, available at <https://fast-dds.docs.eprosima.com/en/latest/>.
247+
4. Apple Developer Documentation, "SwiftUI," available at <https://developer.apple.com/documentation/swiftui>.

0 commit comments

Comments
 (0)