Nowadays, gRPC has become the standard protocol for robot and robot controllers. Various API languages and frameworks, such as REST API, GraphQL, and gRPC, have their pros and cons. However, gRPC stands out for its fast performance and low latency. This is due to gRPC’s binary encoding and its ability to connect via HTTP2.
The Yellow Prince Dog, the Boston Dynamics Spot robot, utilizes the gRPC API to control the robot from a controller or other third-party systems. Boston Dynamics provides an SDK with Python language only to connect to their robot-level gRPC API. There is no C# language SDK for Spot with Microsoft .NET Framework. This presented an opportunity for me to explore the .NET 7 gRPC Tool with the Boston Dynamics Spot API.
To evaluate the ease of creating a gRPC client in C# using .NET 7, let’s embark on a hands-on exercise together. Here’s how we can get started:
To create a gRPC client in C#, you’ll need four packages:
- Google.Protobuf which contains C# runtime library for Protocol Buffers — Google’s data interchange format.
- Grpc.Core which contains C# implementation of gRPC based on native gRPC C-core library.
- Grpc.Net.Client which is a .NET client for gRPC.
- Grpc.Tools which is a gRPC and Protocol Buffer compiler for C# projects.
I crated a .NET Class Library project and added that 4 packages from NuGet Package Manager as below.
The next step is to download the Boston Dynamics Spot gRPC Protobuf files from the Spot SDK GitHub repository. This is necessary because gRPC follows a contract-first API approach, where the API contract is defined using Protocol Buffers (protobuf) files. By downloading these protobuf files, we can generate the necessary client code for interacting with the Spot robot’s gRPC API.
All Protobuf files shall be placed in .NET Project with same folder structure.
After downloading the Protobuf files, select all of them in the solution explorer and change their Build Action to “Protobuf Compiler” This step is important because it configures the Protobuf files to be processed by the Protobuf compiler during the build process. By doing this, the necessary C# code will be generated based on the Protobuf definitions, allowing you to use the generated classes in .NET 7 gRPC client.
After changing the Build Action of the Protobuf files to “Protobuf Compiler”, you also need to set the properties of the generated gRPC stub classes to “Client Only”. This ensures that only the necessary C# code for the client-side implementation is generated, excluding any server-related code.
Now that you have made the necessary changes, proceed to build the .NET Class Library project. Upon building the project in Visual Studio, the Grpc.Core.Tools package will automatically generate the C# class library based on the Protobuf files and the gRPC stub classes. This process allows you to generate the required C# code for interacting with the Boston Dynamics Spot robot’s gRPC API within your .NET project.
With the .NET Class Library project built and the C# class library generated, your Spot robot gRPC C# client library is ready for further development.
The next step is to create a C# wrapper class library that will utilize the gRPC C# client library. By referencing the gRPC C# client library project in a wrapper class library project, you can now utilize the functionality provided by the Spot robot gRPC API within your wrapper class library. This approach allows for a clean separation of concerns and helps encapsulate the gRPC functionality within a dedicated wrapper.
Here is an example of my preferred structure for the wrapper classes in the wrapper class library project, with the same class and method names as the Boston Dynamics protobuf:
Wrapper method implementation is simple. Just create a same function name GetRobotId with RoboIdResponse return type.
1. public static RobotIdResponse GetRobotId(Robot robot)
2. {
3. RobotIdResponse grpcResponse = new RobotIdResponse();
4.
5. var channel = robot.EnsureChannelFor(ServiceEntryName.RobotId);
6. var service_client = new RobotIdService.RobotIdServiceClient(channel);
7.
8. RobotIdRequest grpcRequest = new RobotIdRequest()
9. {
10. Header = new RequestHeader(robot.RequestHeader)
11. };
12.
13. grpcResponse = service_client.GetRobotId(grpcRequest);
14. if (grpcResponse.RobotId != null)
15. robot.Id = grpcResponse.RobotId; // assign back to robot client object
16.
17. return grpcResponse;
18. }
Here is a line-by-line explanation:
- Line 3, just create a ReobotIdResponse variable which is coming from gRPC client C# library.
- Line 5 is channel creation, gRPC channel provides a connection to a gRPC server on a specified host and port.
- Line 6 is gRPC client creation based on the channel.
- Line 8 to 11 are gRPC Request object creation where we can pass the header and parameters.
- Line 13 is using gRPC client C# library and calling to gRPC server method.
- Line 14 and 15 are local wrapper class library design.
- Line 17 is return the gRPC Response.
That’s all.
I created wrapper class for some Boston Dynamic Spot gRPC API function including authentication and heartbeat check-in functions.
Here is test result with physical Spot Robot.
In conclusion, gRPC is a high-performance Remote Procedure Call (RPC) framework. The .NET 7 C# gRPC packages provide a perfect foundation for creating libraries. As a .NET developers, this is the right choice to create a gRPC API for robot-to-controller communication.
Thank you for reading! I hope this article has provided you with valuable insights into utilizing gRPC with the Boston Dynamics Spot robot’s API using .NET 7. If you have any further questions or need clarification on any topic discussed, please feel free to drop a comment. Your feedback is greatly appreciated.
Happy coding!