Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moving eCAL provider to incubation repo #3

Merged
merged 2 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Component | Content | Comment/Status
----------|----------|---------------
[HVAC Service](hvac_service) | Python service example
[Seat Service](seat_service) | C++ service example
[eCAL Provider](ecal2val) | Python provider for [eCAL](https://projects.eclipse.org/projects/automotive.ecal)

## Contribution

Expand Down
53 changes: 53 additions & 0 deletions ecal2val/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# eCAL Feeder
The purpose of this implementation is to input data received via [eCAL](https://projects.eclipse.org/projects/automotive.ecal) into
[KUKSA Databroker](https://github.com/eclipse/kuksa.val/tree/master/kuksa_databroker).
The topics transmitted by eCAL are in the form of protobuf, and based on the VSS description and data outlined in this format,
it is possible to provide data to the databroker via kuksa_client.



## Usage
1. Install Python requirements for both eCAL and KUKSA.val

```
sudo add-apt-repository ppa:ecal/ecal-5.12
sudo apt-get update
sudo apt-get install ecal
sudo apt install python3-ecal5

pip install kuksa-client

```

2. Generate proto_struct_pb2.py in proto directory with following method

```
sudo apt-get install protobuf-compiler

protoc --python_out=. proto_struct.proto

```

3. Use the following command to run the ecal2val.py

```
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python

python3 ecal2val.py

```

This assumes a running `KUKSA.val` databroker at `127.0.0.1:55555`.

4. For testing, run the mock_publisher.py

```
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python

python3 mock_publisher.py

```

Modify proto file to utilize more specific information.

This was successfully tested on Ubuntu 20.04 and eCAL 5.12.
64 changes: 64 additions & 0 deletions ecal2val/ecal2val.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#! /usr/bin/env python3

########################################################################
# Copyright (c) 2024 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License 2.0 which is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
########################################################################

'''
Subscriber subscribing vss topics via ECAL communication
and sending it to KUKSA.val databroker.
'''

import sys
import time

import ecal.core.core as ecal_core
from ecal.core.subscriber import ProtoSubscriber

import proto.proto_struct_pb2 as proto_struct_pb2

from kuksa_client.grpc import Datapoint
from kuksa_client.grpc import DataEntry
from kuksa_client.grpc import EntryUpdate
from kuksa_client.grpc import Field
from kuksa_client.grpc import VSSClient


ecal_core.initialize(sys.argv, "ecal2val")

sub = ProtoSubscriber("vss_topic", proto_struct_pb2.DataEntry)

'''
This callback function subscribes topics
and writes the data to the databroker.
'''


def callback(topic_name, msg, time):
with VSSClient('127.0.0.1', 55555) as client:
entry = DataEntry(
path=msg.path,
value=Datapoint(value=eval(f"msg.value.{msg.data_type}")),
)
updates = (EntryUpdate(entry, (Field.VALUE,)),)

client.set(updates=updates)

print(f'{msg.path} subscribed & written')


sub.set_callback(callback)

while ecal_core.ok():
time.sleep(1)

ecal_core.finalize()
20 changes: 20 additions & 0 deletions ecal2val/mock_data.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Vehicle.Speed 1.0 float
Vehicle.Chassis.SteeringWheel.Angle -40 int32
Vehicle.Speed 1.2 float
Vehicle.Chassis.SteeringWheel.Angle -30 int32
Vehicle.Speed 1.4 float
Vehicle.Chassis.SteeringWheel.Angle -20 int32
Vehicle.Speed 1.6 float
Vehicle.Chassis.SteeringWheel.Angle -10 int32
Vehicle.Speed 1.8 float
Vehicle.Chassis.SteeringWheel.Angle 0 int32
Vehicle.Speed 2.0 float
Vehicle.Chassis.SteeringWheel.Angle 10 int32
Vehicle.Speed 2.2 float
Vehicle.Chassis.SteeringWheel.Angle 20 int32
Vehicle.Speed 2.4 float
Vehicle.Chassis.SteeringWheel.Angle 30 int32
Vehicle.Speed 2.6 float
Vehicle.Chassis.SteeringWheel.Angle 40 int32
Vehicle.Speed 2.8 float
Vehicle.Chassis.SteeringWheel.Angle 50 int32
77 changes: 77 additions & 0 deletions ecal2val/mock_publisher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#! /usr/bin/env python3

########################################################################
# Copyright (c) 2024 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License 2.0 which is available at
# http://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
########################################################################

'''
Publisher publishing vss topics via eCAL communication.
'''

import sys
import time

import ecal.core.core as ecal_core
from ecal.core.publisher import ProtoPublisher

import proto.proto_struct_pb2 as proto_struct_pb2


def string(value):
return str(value)


def int32(value):
return int(value)


def int64(value):
return int(value)


def uint32(value):
return int(value)


def uint64(value):
return int(value)


def double(value):
return float(value)


ecal_core.initialize(sys.argv, "ecal2val")

pub = ProtoPublisher("vss_topic", proto_struct_pb2.DataEntry)

'''
Reads arbitrary data from 'mock_data.txt'
and publishes it in the form of a protobuf message.
'''

while ecal_core.ok():
with open("mock_data.txt", 'r', encoding='utf-8') as file:
for line in file:
path, value, data_type = line.split()

entry = proto_struct_pb2.DataEntry()
entry.path = path
exec(f"entry.value.{data_type} = {data_type}(value)")
entry.data_type = data_type

pub.send(entry)
print(f"{path} published")

time.sleep(1)

ecal_core.finalize()
35 changes: 35 additions & 0 deletions ecal2val/proto/proto_struct.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/********************************************************************************
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License 2.0 which is available at
* http://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

syntax = "proto3";

package proto_struct;

message DataEntry {
string path = 1;
DataPoint value = 2;
string data_type = 3;
}

message DataPoint {
oneof value {
string string = 1;
bool bool = 2;
sint32 int32 = 3;
sint64 int64 = 4;
uint32 uint32 = 5;
uint64 uint64 = 6;
float float = 7;
double double = 8;
}
}