-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update documentation to include getting started and examples
- Loading branch information
Showing
15 changed files
with
253 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# NComm Examples | ||
|
||
### Minimal Publisher Subscriber [`examples/minimal-publisher-subscriber](./minimal-publisher-subscriber/README.md) | ||
|
||
The minimal publisher subscriber example shows how the ROS 2 [Writing a simple publisher and subscriber](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html) tutorial would be completed in NComm. In short, the principle of the example is that there are two Nodes, one that publishes the string "Hello, World! {num}", where num is an incrementing integer that contains the number of times the publisher has published. The client receives this string and prints the string "I header: {message}", where message is the string the publisher published. | ||
|
||
### Minimal Client Server [`examples/minimal-client-server`](./minimal-client-server/README.md) | ||
|
||
The minimal client server example shows how the ROS 2 [Writing a simple service and client](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.html) tutorial would be complete in NComm. In short, the principle of the example is there are two Nodes, one that sends a request for the sum of two integers and one that sends the sum of the two addends back. | ||
|
||
### Minimal Update Client Server [`examples/minimal-update-client-server](./minimal-update-client-server/README.md) | ||
|
||
The minimal update client server example shows how the ROS 2 [Writing an action server and client](https://docs.ros.org/en/humble/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.html) tutorial would be completed in NComm. In short, the principle of the example is that a client asks for the nth term in the Fibonacci sequence and the update server slowly increments from the 0th term to the nth term in the Fibonacci sequence sending the current and previous term in the sequence until it reaches the nth term when it sends the nth term in the sequence back to the client. | ||
|
||
### Rerun Publisher [`examples/rerun-publisher](./rerun-publisher/README.md") | ||
|
||
The rerun publisher example shows a contrived example of how you can connect to the Rerun with NComm. In the example, a node publishes data sampled from a normal distribution to an instance of Rerun instantiated by creating a Rerun node. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Minimal Client Server | ||
|
||
## Description | ||
|
||
In this example, you spin up two nodes in a single-threaded executor. One of the nodes is a simple client who asks the server for the sum of two numbers (a and b). The server node then responds with the sum of the two numbers. | ||
|
||
## Running | ||
|
||
To run this example ensure you are in the example's base directory and run: | ||
```sh | ||
cargo run | ||
``` | ||
|
||
## Breakdown | ||
|
||
### [NodeIdentifier](./src/main.rs) | ||
|
||
In NComm, all nodes need some sort of identifier so they can be added and removed from the Executor. The only requirement for this identifier is that the identifier must implement `PartialEq`. In this example, I used an enum, but you can just as easily use any other equatable type. | ||
|
||
### [AddTwoIntsRequest and AddTwoIntsResponse](./src/main.rs) | ||
|
||
In NComm, there is no need to use message files because everything is Rust. Instead, you can define your own types (as well as methods) as message data. In this example, The `AddTwoIntsRequest` is a struct consisting of two fields `a` and `b` which are both `u64`s. The response type, `AddTwoIntsResponse` consists of a singular field `sum` which is a `u64`. | ||
|
||
### [Minimal Client](./src/minimal_client.rs) | ||
|
||
The `MinimalClient` has a `LocalClient` that sends `AddTwoIntsRequest`s as requests and receives `AddTwoIntsResponses` as responses. The `MinimalClient` also has an update_delay of 500,000us which means that its update function is called every 500,000us. Every `update`, the `MinimalClient` sends a request containing two random `u64`s and checks for incoming responses. If there are responses, the `MinimalClient` prints "{a} + {b} = {sum}", where a and b are the requested addends and sum is their sum. | ||
|
||
### [Minimal Server](./src/minimal_server.rs) | ||
|
||
The `MinimalServer` has a `LocalServer` that receives `AddTwoIntsRequest`s and responds with `AddTwoIntsResponses`. The `MinimalServer` also has an update delay of 500,000us which means that its update function is called every 500,000 microseconds. Every `update`, the server checks for incoming requests and responds with the sum of the addends. | ||
|
||
### [Simple Executor](./src/main.rs) | ||
|
||
In the main function, we create a `SimpleExecutor` to execute the Nodes. The simple executor is a single threaded executor that maintains a queue of nodes to execute and runs their update function every update delay. For more information on executors, see the `ncomm-executors` documentation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Minimal Publisher Subscriber | ||
|
||
## Description | ||
|
||
In this example you spin up two nodes in a single-threaded executor. One of the nodes is a simple publisher who publishes the message "Hello, World! {count}" to a subscriber who prints the message to the console. | ||
|
||
## Running | ||
|
||
To run this example ensure you are in the example's base directory and run: | ||
```sh | ||
cargo run | ||
``` | ||
|
||
## Breakdown | ||
|
||
### [NodeIdentifier](./src/main.rs) | ||
|
||
In NComm, all nodes need some sort of identifier so they can be found inside of the Executor. The only requirement for this identifier is that is must implement PartialEq so Node's with a given identifier can be found inside of an executor. | ||
|
||
### [Minimal Publisher](./src/minimal_publisher.rs) | ||
|
||
The `MinimalPublisher` has a `LocalPublisher` that can be used to send strings. Every 500,000 microseconds, the `MinimalPublisher` sends the string "Hello, World! {count}", where count is the number of times the publisher has published the string "Hello, World!" to the subscriber. | ||
|
||
### [Minimal Subscriber](./src/minimal_subscriber.rs) | ||
|
||
The `MinimalSubscriber` has a `LocalSubscriber` that subscribes to receive strings. Every 500,000 microseconds, the `MinimalSubscriber` checks the currently published string message from the publisher and prints "I heard: {message}", where message is the "Hello, World! {count}" value from the publisher. | ||
|
||
### [Simple Executor](./src/main.rs) | ||
|
||
In the main file, a SimpleExecutor is created an populated with an owned heap pointer to the nodes. This executor will then execute the `update` methods on the nodes at their update rate (500,000 microseconds). For more information on executors, see the `ncomm-executors` documentation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Minimal Update Client Server | ||
|
||
## Description | ||
|
||
In this example, you spin up two nodes, the `FibonacciUpdateClient` node requests the 10th number in the fibonacci sequence from the `FibonacciUpdateServer` node. | ||
|
||
## Running | ||
|
||
To run this example ensure you are in the example's base directory and run: | ||
```sh | ||
cargo run | ||
``` | ||
|
||
## Breakdown | ||
|
||
### [NodeIdentifier](./src/main.rs) | ||
|
||
In NComm, all nodes need some sort of identifier so they can be found inside of the Executor. The only requirement for this identifier is that is must implement PartialEq so Node's with a given identifier can be found inside of an executor. | ||
|
||
### [FibonacciRequest, FibonacciUpdate, and FibonacciResponse](./src/main.rs) | ||
|
||
The update client sends a FibonacciRequest asking for the nth term in the Fibonacci sequence. Then, as the update server is calculating the nth term, the update server will update the update client with a `FibonaciUpdate`, which consists of the current term in the sequence as well as the previous number in the sequence. Finally, once the update server has reached the nth term in the Fibonacci sequence, the update server sends a `FibonacciResponse` containing the nth term in the sequence | ||
|
||
### [FibonacciUpdateClient](./src/fibonacci_update_client.rs) | ||
|
||
The `FibonacciUpdateClient` has a `LocalUpdateClient` that sends `FibonacciRequest`s and receives `FibonacciUpdate`s as updates and finally a `FibonacciResponse` as a response. Every 100,000 microseconds, the update client checks for any incoming updates from the update server and prints "Last Num: {last_num} --- Current Num: {current_num}", where last_num is the last number in the Fibonacci sequence and current_num is the current number in the Fibonacci sequence. Then, the update client checks if there are incoming responses. If there is an incoming response, the update client prints "f(10) = {nth_term}", where nth_term is the nth term in the Fibonacci sequence before sending another request for the 10th term in the Fibonacci sequence. | ||
|
||
### [FibonacciUpdateServer](./src/fibonacci_update_server.rs) | ||
|
||
The `FibonacciUpdateServer` has a `LocalUpdateServer` that receives `FibonacciRequest`s and sends `FibonacciUpdate`s as updates before sending a `FibonacciResponse` as the final response. Every 100,000 microseconds, the update client checks for incoming requests, setting any incoming requests as the current request to handle. Then, it increments its current term in the Fibonacci sequence before sending an update the the client with the current and last number in the Fibonacci sequence. Finally, if the update server has the 10th term in the Fibonacci sequence, the update server sends a response containing the 10th term in the Fibonacci sequence to the update client. | ||
|
||
### [ThreadPoolExecutor](./src/main.rs) | ||
|
||
In the main method, we create a `ThreadPoolExecutor` to execute the Nodes. In all reality there is no need to use a `ThreadPoolExecutor` in this context as there are only two nodes so one thread can probably schedule the Nodes just fine. However, to demonstrate how to use another one of the executors provided in the `ncomm-executors` crate, I figured it would make sense to use a ThreadPoolExecutor with 3 threads in the ThreadPool. For more information on executors, see the `ncomm-executors` documentation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Rerun Publisher | ||
|
||
## Description | ||
|
||
In this example, one Node is spun up that publishes data randomly selected from a normal distribution with a mean of 1 and standard deviation of 1 to a spawned instance of the Rerun data visualizer. Although this is arguably a very contrived example of using Rerun with NComm, I would argue that it gives the user a good idea of how to use Rerun with NComm. | ||
|
||
## Running | ||
|
||
To run this example ensure you are in the example's base directory and run: | ||
```sh | ||
# If you don't already have the rerun-cli installed | ||
cargo install rerun-cli | ||
cargo run | ||
|
||
# If you already have the rerun-cli installed | ||
cargo run | ||
``` | ||
|
||
## Breakdown | ||
|
||
### [NodeIdentifier](./src/main.rs) | ||
|
||
In NComm, all nodes need some sort of identifier so they can be added and removed from the Executor. The only requirement for this identifier is that the identifier must implement `PartialEq`. In this example, I used an enum, but you can just as easily use any other equatable type. | ||
|
||
### [Data Collection Node](./src/data_collection_node.rs) | ||
|
||
The data collection node has an OS Random number generator, a Normal distribution, and a RerunPublisher that publishes Scalars to a string path. The node's update loop is run every 10,000 microseconds and involves the node selecting a piece of data from the normal distribution and publishing that data to the running Rerun instance. | ||
|
||
### [Rerun Node](./src/main.rs) | ||
|
||
The Rerun node is more or less a convenience Node. All it does is during the `start` state it connects to or spawns a rerun instance and saves the data from the current Rerun session to an optional output_path. It also makes it easy to create publishers for the Rerun session it is managing by offering a convenience method to create rerun publishers. | ||
|
||
### [Simple Executor](./src/main.rs) | ||
|
||
In the main method, we create a `SimpleExecutor` to execute the Nodes. In reality, the `RerunNode` doesn't do anything during the `update` state so the simple executor is only calling `update` on the `DataCollectionNode` so a `SimpleExecutor` is more than enough for the situation. | ||
|
||
## Note | ||
|
||
This example only opens Rerun the first time it is run, so if you don't see any data logged to Rerun the first time you run the example, run it again and then you'll see the data populate the Rerun viewer. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.