Skip to content

Commit

Permalink
feat(veristand-controller): send data in protobuf over zeromq (#20474)
Browse files Browse the repository at this point in the history
  • Loading branch information
hongbo-miao authored Nov 14, 2024
1 parent a9b6eb0 commit dbb0ecf
Show file tree
Hide file tree
Showing 18 changed files with 205 additions and 82 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ data-visualization/grafana/hm-panel-plugin/.config
desktop-qt/CMakeLists.txt.user
embedded/decode-can-data/data
hardware-in-the-loop/national-instruments/hm-tdms/data
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj
hm-kafka/kafka-client/kafka-c/*/config.ini
kubernetes/certificates
kubernetes/data/config-loader
Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ data-visualization/metabase/plugins
desktop-qt/CMakeLists.txt.user
embedded/decode-can-data/data
hardware-in-the-loop/national-instruments/hm-tdms/data
hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/bin
hardware-in-the-loop/national-instruments/VeriStandController/VeriStandController/obj
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj
hm-kafka/kafka-client/kafka-c/*/config.ini
kubernetes/certificates
kubernetes/data/config-loader
Expand Down
3 changes: 3 additions & 0 deletions .markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@
"desktop-qt/CMakeLists.txt.user",
"embedded/decode-can-data/data",
"hardware-in-the-loop/national-instruments/hm-tdms/data",
"hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages",
"hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin",
"hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj",
"hm-kafka/kafka-client/kafka-c/*/config.ini",
"kubernetes/certificates",
"kubernetes/data/config-loader",
Expand Down
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ data-visualization/metabase/plugins
desktop-qt/CMakeLists.txt.user
embedded/decode-can-data/data
hardware-in-the-loop/national-instruments/hm-tdms/data
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj
hm-kafka/kafka-client/kafka-c/*/config.ini
kubernetes/certificates
kubernetes/data/config-loader
Expand Down
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ AllCops:
- 'desktop-qt/CMakeLists.txt.user'
- 'embedded/decode-can-data/data/**/*'
- 'hardware-in-the-loop/national-instruments/hm-tdms/data/**/*'
- 'hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages/**/*'
- 'hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin/**/*'
- 'hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj/**/*'
- 'hm-kafka/kafka-client/kafka-c/*/config.ini'
- 'kubernetes/certificates/**/*'
- 'kubernetes/data/config-loader/**/*'
Expand Down
3 changes: 3 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ exclude = [
"desktop-qt/CMakeLists.txt.user",
"embedded/decode-can-data/data",
"hardware-in-the-loop/national-instruments/hm-tdms/data",
"hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages",
"hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin",
"hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj",
"hm-kafka/kafka-client/kafka-c/*/config.ini",
"kubernetes/certificates",
"kubernetes/data/config-loader",
Expand Down
3 changes: 3 additions & 0 deletions .solhintignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ data-visualization/metabase/plugins
desktop-qt/CMakeLists.txt.user
embedded/decode-can-data/data
hardware-in-the-loop/national-instruments/hm-tdms/data
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj
hm-kafka/kafka-client/kafka-c/*/config.ini
kubernetes/certificates
kubernetes/data/config-loader
Expand Down
3 changes: 3 additions & 0 deletions .sqlfluffignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ data-visualization/grafana/hm-panel-plugin/.config
data-visualization/metabase/plugins
desktop-qt/CMakeLists.txt.user
hardware-in-the-loop/national-instruments/hm-tdms/data
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj
hm-kafka/kafka-client/kafka-c/*/config.ini
kubernetes/certificates
kubernetes/data/config-loader
Expand Down
3 changes: 3 additions & 0 deletions .stylelintignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ data-visualization/metabase/plugins
desktop-qt/CMakeLists.txt.user
embedded/decode-can-data/data
hardware-in-the-loop/national-instruments/hm-tdms/data
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj
hm-kafka/kafka-client/kafka-c/*/config.ini
kubernetes/certificates
kubernetes/data/config-loader
Expand Down
3 changes: 3 additions & 0 deletions .yamllint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ ignore: |
desktop-qt/CMakeLists.txt.user
embedded/decode-can-data/data
hardware-in-the-loop/national-instruments/hm-tdms/data
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/packages
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/bin
hardware-in-the-loop/national-instruments/VeriStandZeroMQBridge/VeriStandZeroMQBridge/obj
hm-kafka/kafka-client/kafka-c/*/config.ini
kubernetes/certificates
kubernetes/data/config-loader
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,8 @@ make kubernetes-clean
### Network Programmability

- **P4** - Programming Protocol-independent Packet Processors
- **ZeroMQ** - High-performance asynchronous messaging library
- **NetMQ** - C# implementation of ZeroMQ

### Communication Standards

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VeriStandController", "VeriStandController\VeriStandController.csproj", "{D99D3F07-09BA-49F2-B4A4-D65AAB41C037}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VeriStandZeroMQBridge", "VeriStandZeroMQBridge\VeriStandZeroMQBridge.csproj", "{D99D3F07-09BA-49F2-B4A4-D65AAB41C037}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,75 @@
using NationalInstruments.VeriStand.ClientAPI;
using NetMQ;
using NetMQ.Sockets;
using NationalInstruments.VeriStand.ClientAPI;
using System;
using System.Diagnostics;
using Google.Protobuf;
using System.Linq;
using VeriStandZeroMQBridge;

namespace VeriStandController
public class Program
{
internal class Program
{
private const string GATEWAY_IP = "localhost";
private const string SYSTEM_DEFINITION_PATH = @"C:\Users\Public\Documents\National Instruments\NI VeriStand 2024\Examples\Stimulus Profile\Engine Demo\Engine Demo.nivssdf";
private const int TOTAL_MESSAGES = 100000;
private const int INTERVAL_MS = 5000;
private const int CONNECTION_TIMEOUT_MS = 60000;
private const string GATEWAY_IP = "localhost";
private const string SYSTEM_DEFINITION_PATH = @"C:\Users\Public\Documents\National Instruments\NI VeriStand 2024\Examples\Stimulus Profile\Engine Demo\Engine Demo.nivssdf";
private const int TOTAL_MESSAGES = 100000;
private const int INTERVAL_MS = 5000;
private const int CONNECTION_TIMEOUT_MS = 60000;
private const string ZMQ_ADDRESS = "tcp://*:5555";

public static void Main(string[] args)
public static void Main(string[] args)
{
using (var publisher = new PublisherSocket())
{
publisher.Bind(ZMQ_ADDRESS);
Console.WriteLine($"[ZMQ] Publisher bound to {ZMQ_ADDRESS}");

try
{
var workspace = new Factory().GetIWorkspace2(GATEWAY_IP);

// Get aliases and channels
string[] aliases, channels;
workspace.GetAliasList(out aliases, out channels);
Console.WriteLine($"[Config] Aliases: {string.Join(", ", aliases)} | Channels: {string.Join(", ", channels)}");

// Initialize values array and connect to system
double[] values = new double[aliases.Length];
workspace.ConnectToSystem(SYSTEM_DEFINITION_PATH, true, CONNECTION_TIMEOUT_MS);
Console.WriteLine("[Status] Data collection started");

// Setup monitoring variables
int messageCount = 0;
int messagesLastInterval = 0;
var totalStopwatch = Stopwatch.StartNew();
var intervalStopwatch = Stopwatch.StartNew();

// Main data collection loop
while (messageCount < TOTAL_MESSAGES)
{
workspace.GetMultipleChannelValues(aliases, out values);
var signals = new Signals
{
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
Signals_ = { aliases.Zip(values, (alias, value) =>
new Signal {
Alias = alias,
Value = value
}) }
};

// Serialize and send
byte[] data = signals.ToByteArray();
publisher.SendFrame(data);

messageCount++;
messagesLastInterval++;

if (intervalStopwatch.ElapsedMilliseconds >= INTERVAL_MS)
{
double messagesPerSecond = messagesLastInterval / (intervalStopwatch.ElapsedMilliseconds / 1000.0);
Console.WriteLine($"[Update] Speed: {messagesPerSecond:F2} msg/s | Total: {messageCount:N0} | Values: {string.Join(", ", values)}");
Console.WriteLine($"[Update] Speed: {messagesPerSecond:F2} msg/s | Total: {messageCount:N0} | Value Count: {values.Length}");
// Console.WriteLine($"Values: {string.Join(", ", values)}");

messagesLastInterval = 0;
intervalStopwatch.Restart();
}
}

// Display final statistics
double totalTime = totalStopwatch.Elapsed.TotalSeconds;
double averageMessagesPerSecond = TOTAL_MESSAGES / totalTime;
Console.WriteLine($"[Complete] Runtime: {totalTime:F2}s | Avg Speed: {averageMessagesPerSecond:F2} msg/s | Total Messages: {TOTAL_MESSAGES:N0}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("VeriStandController")]
[assembly: AssemblyTitle("VeriStandZeroMQBridge")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VeriStandController")]
[assembly: AssemblyProduct("VeriStandZeroMQBridge")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
syntax = "proto3";

option csharp_namespace = "VeriStandZeroMQBridge";

message Signals {
int64 timestamp = 1;
repeated Signal signals = 2;
}

message Signal {
string alias = 1;
double value = 2;
}
Loading

0 comments on commit dbb0ecf

Please sign in to comment.