Multithreading and ROS

This week I’ve been digging into Robot Operating System (ROS) and how our project will make use of functional components of ROS. The eGreenhouse that we are working on will use ROS to coordinate the end effector movement and data collection, following instructions received from the user interface. The portion that I’ve been working on sends a series of instructions to the Grbl CNC controller. A second node monitors the position of the end effector and triggers data collection actions. Once the destination is reached, an image or set of environmental sensor readings are collected and the next destination is sent to the CNC controller. This process is relatively straight forward – go to a location, collect some data, go to the next point, and repeat. But it gets interesting in the context of the whole machine and the mechanisms that ROS provides to make it work.

ROS nodes are processes which run independently of one another and communicate through topics and services. As a quick 10 cent description, topics are unidirectional communication channels which nodes may either publish or subscribe to in a one to one, one to many, or many to many relationship. A topic is effectively a queue of messages sent from the publisher to the subscriber. Each node which subscribes to a given topic receives all messages published to that topic. Services are a bidirectional communication channel where individual requests and responses sent between nodes in a one to one relationship. Topics and services provide a convenient means for nodes to execute their respective series of functions or run a microcontroller asynchronous of one another but still pass data among them when any events of interest occur. It has been particularly fun to learn about the parallelism that is created through this organization. When a node receives a request through a service, it spins off a new thread to handle the request through the specified handler function. The sending node blocks until the response to the request is received. Each topic subscriber runs its own thread. When messages queue up on a topic, each is processed in the order they are received. Each message received on a topic is processed in the order that it was received, but if a node subscribes to multiple topics, they operate concurrently.

As I’ve been working on this project it has been thought provoking to design the interactions for each node around the implications of the built in thread structure. I’ve also incorporated some additional multithreading to handle executing each set of way points. This week I’ve been working on the node which receives requests from the front end, the PathPlanner node. The requests will contain a unique id of the program to run. Our database contains a table of waypoints, each assigned to a given program id. Each waypoint is associated with a location in the study plot and an instruction to collect either an image or a set of sensor readings needs to be collect. When the node is started, it spins off a new thread which watches for program ids in a queue. As program ids are removed from the queue, the watching thread of the PathPlanner node queries the database for the set of waypoints for that program and sends them to the CNC controller, one at a time so that data can be collected. Meanwhile, the main thread is watching the service for additional requests. This way, if the user wants to execute another program before the current one is complete, the id can be added to the queue and executed when the time comes. To make this work, this node manages two concurrently running threads, processes incoming service requests, and publishes instructions to an outbound topic.

A City on the Water

This week I had initially planned to write about the some ROS concepts or maybe expressing some interest in the new computers Apple announced this week. But today I had to make an early morning trip from Seattle to Whidbey Island on one of the ferries which I hadn’t taken in quite a few years and thought it might be nice to reflect on.

Seattle is located between Lake Washington and Puget Sound which together make a number of natural obstacles that the city has been built around. Puget Sound runs from about 25 miles south of Seattle, to about 40 miles north where it meets the Salish Sea and the Straight of Georgia around the San Juan Islands. The ferry system has become its own sort of tourist attraction. People from visiting from out of town often will make crossings for the novelty and similarly, locals often make weekend trips to the peninsulas and islands via ferry.

But the ferries aren’t just a recreational curiosity. Thanks to development throughout the region on the west side of the sound and the islands, Seattle has relied on the ferries keep the region connected. A significant number of people in the area rely on the system as part of their daily commute and contractors frequently find themselves able to provide services throughout the Puget Sound region on a scale that wouldn’t be possible without the ferries. When I was a consultant, I worked on ongoing projects in Port Orchard, Bremerton, and Whidbey Island which were all easily serviceable thanks to the ferries. West across the sound from Seattle is Bainbridge Island where many people commute downtown for work and similarly people commute from Whidbey Island to Mukilteo, often to work north of Seattle at Boeing or their various contractors.

The ferries are an integral part of life around the Sound, but along with many other industries have been struck with labor shortages. In recent weeks the various crossings have all had to cut service by 30 to 50% each day. Fortunately for my trip today this was only a minor inconvenience since I was traveling counter to most morning commuters. We all hope that service may be returned to full capacity before long, but until then, with a little extra planning, crossing the Sound is still one of my favorite spots to catch the sunrise in town.

A New Paradigm

This morning I’m on the run, so I’ve started my morning with a hot cup of drip coffee from one of my old favorite coffee shops. Here in Seattle, you’re pretty much always within shouting distance of a coffee shop and with so many options it can border on overwhelming where to buy coffee. I’ve been a fan of Seven coffee roasters for years since I was living in the area. Now they’re a little farther out of the way for me, but when I’m in the area it’s worth a stop. Today I’ve got a cup of their Honolulu Hawaiian blend. It’s bright, floral, and most important for today – it’s a quick stop along my morning errands.

Over the past week I’ve been getting started with Robot Operating System (ROS) concepts. In general, ROS programs consist of the core package which tracks nodes, topics, services, and manages the parameter server. The individual executable components of code in a ROS system are known as nodes, and run their respective sets of methods to operate the components of a system. ROS nodes can communicate with each other either through topics or services. Services are similar to the familiar request/response concept we are familiar with through HTTP, allowing individual nodes to communicate with one another.

Topics make use of the publisher/subscriber model. The pub/sub model is a many-to-many communication bus which allows nodes to publish data to topics and all nodes subscribed to a specific topic will receive that data rather than the one-to-one request/response model. Topics are defined by the data type they transfer and publishers must adhere to the data type for the give topic, this may be primitive types or C-style structs. Through this model, a program can run on a central controlling computer and each node is able to independently operate its respective service whether it be an internal operation or running an external micro controller. This allows for additional nodes which make use of common data to be subscribe to the same topic to receive the same events. By using this paradigm, a system can scale up the number of nodes or repurpose data in an asynchronously running program. I’ve previously been aware of this communication paradigm, but never worked with it before. I’m looking forward to continuing to learn about it given its suitability for robotics and IoT devices.

A Familiar Motivation

Ahh, the comforting rumble of the Moka pot starts my morning with a batch of Peet’s house blend. In case you’re unfamiliar with this classic stovetop “espresso” maker, here is an interesting video from Wikipedia showing how it works. Essentially, there is a lower water chamber, a filter funnel, and an upper coffee chamber. As the water is heated, the generated pressure displaces the water and forces it up through the filter funnel. The pressure-brewed coffee is then dispensed into the brew chamber. This brewing method creates coffee which is somewhere between a French Press and espresso in body and strength. I use quotes when describing it as stovetop espresso since it is a similar brew, but purists will quickly point out that it brews using lower pressure than true espresso for extraction. I’m drawn to this simple device over a true espresso machine not only due to the lower price and space necessary for a espresso machine, but also the nuance in using it. The Moka pot has a reputation for producing inconsistent brews which can turn out bitter and over-brewed if proper care isn’t taken. As for me, I enjoy the morning thermodynamics experiment as part of my coffee routine.

This week I thought I’d talk about some of the motivation of why I’m interested in the robotic greenhouse project. The robotic greenhouse shares several attributes with a project that I’ve thought about on numerous occasions, but haven’t been able to set aside enough time to work on. The idea is simple, collect environmental data in an orchidarium and display it through a web interface. A seemingly canonical Arduino project – collect data using inexpensive sensors, supplied in almost every starter kit, then to manipulate and display that data.

This project could be completed in any number of ways, ranging from simple data collection to creating a fully automated environment with a web interface. My initial ideas prior to starting CS 467 consider the issues of scalability and reliability in a small, home-based system. My use case consists of using wi-fi capable Arduinos to collect temperature, humidity, and light data in an orchidarium. This data would then be sent to a Node.js server where it is added to a database. This server would also host the front end which, at a minimum, will show current and historical environmental data in a static web page. The concept is that each Arduino would function as a data module which would collect data from any set of sensors. Multiple Arduinos could then be transmitting data to the server. This would allow scaling to additional sensors or even automating watering and lighting systems or collecting data from multiple locations within in a home since a user may have multiple such controlled environments and want to monitor environmental data from each.

To improve the reliability of this system, the sensor modules would need to be able to handle server down-time. The system that I’ve been conceptualizing is based in a single home. As such, outages are most likely to be power outages affecting the server as well as the sensor modules. Should a situation arise where the server goes down while the sensor modules are still functioning, they should be capable of logging data locally until connection to the server is restored. To solve this problem, each time a data point is collected, a request would be sent to the server in attempt to transfer this newly collected data. If the server is unavailable, the collected data would be stored on the Arduino’s memory. At each time interval, the Arduino continues to attempt a request to the server. As long as the request fails, the collected data is stored locally. When the connection succeeds, any data stored locally is sent, along with the data point collected from the current time interval. Once the stored data is successfully sent to the server, it can be deleted from local memory on the Arduino.

Although this system that I’ve been considering is quite simple, I am excited to contribute to a similar project. Naturally, more will follow in the coming weeks.