We built PolySync after working with the world’s best developers in autonomous driving. We saw that their time and resources were consumed by backend infrastructure, tasks such as parsing, synchronization, reference frame correction, and inter-process communication, all of which are the source of huge costs and reliability problems. PolySync automatically takes care of this complexity, freeing developers to focus on their applications, making their work simpler, faster, and more stable.
What is PolySync?
PolySync is a platform (which we call an "autonomy operating system") consisting of a middleware and set of services that are common across autonomous driving applications. Take a look at the following diagram: PolySync separates the application layer from the underlying OS and hardware, making it more consistent to build and much more portable.
In the diagram, you can see that a variety of applications can utilize the PolySync middleware layer. These applications are performing the important functions for autonomous driving, like perception and control. Let's take a closer look at the PolySync layer to understand what type of functionality it provides.
At the lowest level you can see the three types of inter-process communications (IPC) provided by PolySync:
- Publisher/Subscriber - a type of communications architecture where a single node can broadcast messages to many listeners simultaneously and where a single node can listen to many broadcasters simultaneously.
- Get/Set - a type of communications architecture where applications can be queried for different parameters and will return their current values ("get"). In some cases, these values can be remotely changed ("set").
- Shared Memory - when nodes are interfacing with very high bandwidth data such as video frames, shared memory provides a queue that allows easy access for all other nodes on a single host computer.
In addition to IPC, PolySync provides a variety of helpful services, including:
- Hardware abstraction
- Host abstraction
- Time services
- Coordinate frame transformation
- Record and replay
Autonomy systems usually need to handle a lot of data asynchronously and perform complex operations in real-time. Often a single machine becomes a bottleneck, so it's important to be able to distribute tasks to a variety of computing hardware across a network.
A middleware is a software layer that helps distributed applications communicate seamlessly. PolySync utilizes an amazing middleware layer called Data Distribution Service (DDS). We configure the system as a series of computers that we call Electronic Control Units or ECUs all interconnected via Ethernet. All applications that run on each system and communicate over the middleware are called nodes.
PolySync ships with some important pre-made nodes:
- Dynamic Driver Nodes are responsible for interfacing with supported hardware and often include support for diagnostics, parameters, and special data types.
- PolySync Manager Node handles interfacing with ECUs at the system level, time synchronization between ECUs, and management of all other nodes on the ECU. Only one per host.
Once you get the middleware up and running, you can build your own application nodes to do things like interface with unsupported sensors, plan a motion path, or process incoming sensor data for objects.
A PolySync runtime system is kicked off by the PolySync Manager Node on each ECU. Only one Manager Node can exist for each host and they are responsible for instantiating and killing other nodes, among other things. You can tell them how to do this by using the System Design File, or SDF, which is a unified file that defines the entire PolySync runtime system. Typically this file is edited on one ECU using the SDF Configurator utility and then synchronized to all ECUs.
When it's time to start up the runtime system, the Manager Nodes start first, reference the SDF, and start up their "child" nodes. All you need to build a working PolySync system is a valid SDF.
Abstracted data model
PolySync's main form of communication is using a set of pre-defined messages that are broadcast and received using a publisher/subscriber model. We ship with a core data model which includes some typical types of data that we often see on automated vehicles as well as our own messages that enable some of the API functionality.
The data model provides an abstraction layer that separates data consumers (your program nodes) from data producers (Dynamic Drivers). All the data within each message is in the vehicle-centered reference coordinate frame and is time stamped with UTC time. This makes it easy to swap out hardware and software without breaking the system.
Example of Sensor Abstraction
Let's look at one of our Dynamic Drivers for the Ibeo Lux laser scanner. This is a sophisticated sensor that generates a point cloud, performs object recognition and requires ego-motion of the platform. Architecturally, the Dynamic Driver for the Lux looks like this:
So the Dynamic Driver abstracts what we call the "native bus" of the sensor (in this case Ethernet and CAN) into a set of generalized data types on the PolySync bus. Once these messages are published, they are available to any other participant on the bus. They also contain any data generated by other sensors or processes as well.
For instance, the ps_lidar_point_stream_msg contains the LiDAR points generated by each of the LiDAR sensors on the bus. Each LiDAR point contains generalized data:
|sensor description||native timestamp||echo number||echo pulse width||layer||X position||Y position||Z position|
- sensor description - a string name for the sensor
- native timestamp - some sensor provide their own timestamps, which can be very useful
- echo number - used for LiDAR that support multiple returns (through transparent objects, for example)
- echo pulse width - duration of energy return
- layer - scanning LiDAR usually return multiple "layers" of data in horizontal lines
- positions - the position of the point, returned in vehicle centered reference frame
There is also a header that contains:
|message type||timestamp||source GUID|
- message type - a string name for the sensor
- timestamp - usually a UTC timestamp that comes from GPS
- source GUID - a unique identifier for the node, generated by PolySync at runtime
Get/Set and Parameters
Publisher/subscriber isn't ideal for all types of communication on an autonomy system. PolySync also includes the ability to query and set parameters using a get/set communications system. All the Dynamic Drivers ship with a complete parameter set that lets you change a lot of their features during runtime, like mounting position, operating states, and what kind of filters are active. Here's a few of them for the Lux Dynamic Driver, pulled from our documentation:
Any node on the PolySync network can utilize the get/set framework to easily implement runtime configurability. Every node automatically is able to publish and subscribe to the ps_parameter_msg and maintains a real-time database of available parameters and their status.
PolySync also includes some useful tools to help you build and debug your runtime system.
- Studio - visualize data from the PolySync bus
- SDF Configurator - a utility program to help you define the runtime system, containing hosts and nodes
- Data Model Generator - a utility to generate custom message types to be used by the publisher/subscriber network
- License Tool - a utility to interact with licensing
Now that you've got an understanding of the fundamentals, you might be interested in learning more about specific applications of PolySync. Next take a look at the Hello World tutorial to learn how to create a PolySync node or jump straight to Hello World with Two Nodes tutorial to learn about building a distributed system.