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

implement simple data types #1

Merged
merged 3 commits into from
Sep 21, 2023
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
20 changes: 20 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Tests
on: [push]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: "3.9"

- name: Run image
uses: abatilo/actions-poetry@v2
with:
poetry-version: "1.6.1"

- run: make install
- run: make test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vscode
__pycache__
51 changes: 0 additions & 51 deletions FrontLights.cpp

This file was deleted.

4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
.PHONY: install
install:
poetry install

.PHONY: test
test:
poetry run pytest
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Telemetry Parsing Codegen

To eliminate repetitive code, this module takes in a yaml file with the schema of the CAN messages, and generates the cpp modules needed to parse the CAN messages.
23 changes: 0 additions & 23 deletions config.yml

This file was deleted.

Empty file added datamodule/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions datamodule/cpp/DataModuleInfo.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* DataModuleInfo.hpp
*
* THIS IS AUTO GENERATED. DO NOT EDIT
*/

#ifndef SOLARGATORSBSP_DATAMODULES_INC_DATAMODULEINFO_HPP_
#define SOLARGATORSBSP_DATAMODULES_INC_DATAMODULEINFO_HPP_


namespace SolarGators::DataModuleInfo
{
// ---- Addresses ---- //

{% for message in canMessages %}
static constexpr uint32_t {{ message["name"] }}_ID = {{ message["id"] }};
{% endfor %}
}


#endif /* SOLARGATORSBSP_DATAMODULES_INC_DATAMODULEINFO_HPP_ */
28 changes: 20 additions & 8 deletions datamodule/cpp/module.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
#include <{{ moduleName }}.hpp>
#include <DataModuleInfo.hpp>
/*
* {{ moduleName }}.cpp
*
* THIS IS AUTO GENERATED, DO NOT EDIT.
*/

#include "{{ moduleName }}.hpp"
#include "DataModuleInfo.hpp"
#include <cstring>

namespace SolarGators {
namespace DataModules {
Expand All @@ -8,9 +15,12 @@ namespace {
}

{{ moduleName }}::{{ moduleName }}():
DataModule(SolarGators::DataModuleInfo::FRONT_LIGHTS_ID, 0, SIZE),
DataModule(SolarGators::DataModuleInfo::{{ moduleName }}_ID, 0, SIZE),
{% for attribute in attributes %}
{{ attribute["name"] }}({{ attribute["default"] }})
{% if not loop.last %}
,
{% endif %}
{% endfor %}
{ }

Expand All @@ -26,17 +36,19 @@ namespace {

void {{ moduleName }}::ToByteArray(uint8_t* buff) const
{
size_t index = 0;
{% for attribute in attributes %}
{%- for byte in range(attribute["bytes"]) %}
buff[{{ byte }}] = static_cast<uint8_t>({{ attribute["name"] }} >> {{ byte }});
{% endfor %}
memcpy(buff + index, &{{ attribute["name"] }}, sizeof({{ attribute["name"] }}));
index += sizeof({{ attribute["name"] }});
{% endfor %}
}

void {{ moduleName }}::FromByteArray(uint8_t* buff)
{
size_t index = 0;
{% for attribute in attributes %}
// TODO: This one is much harder and prone to error
throttle_ = static_cast<uint16_t>(buff[1]) << 8 | buff[0];
memcpy(&{{ attribute["name"] }}, buff + index,sizeof({{ attribute["name"] }}));
index += sizeof({{ attribute["name"] }});
{% endfor %}
}

Expand Down
26 changes: 12 additions & 14 deletions datamodule/cpp/module.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
/*
* FrontLights.hpp
*
* Created on: Jan 17, 2022
* Author: John Carr
* THIS IS AUTO GENERATED, DO NOT EDIT
*/

#ifndef SOLARGATORSBSP_STM_DATAMODULES_INC_FRONTLIGHTS_HPP_
#define SOLARGATORSBSP_STM_DATAMODULES_INC_FRONTLIGHTS_HPP_

#include <DataModule.hpp>
#include "DataModule.hpp"
#define BUFF_SIZE 50

namespace SolarGators {
namespace DataModules {

class FrontLights: public DataModule {
class {{ moduleName }}: public DataModule {
public:
FrontLights();
~FrontLights();
uint16_t GetThrottleVal() const;
bool GetBreaksVal() const;
uint8_t buffCtr;
uint16_t breaksBuffer[BUFF_SIZE];
{{ moduleName }}();
~{{ moduleName }}();
{% for attribute in attributes %}
{{ attribute["type"] }} Get{{ attribute["name"] }}Val() const;
{% endfor %}

// CAN Functions
void ToByteArray(uint8_t* buff) const;
void FromByteArray(uint8_t* buff);
Expand All @@ -30,10 +29,9 @@ class FrontLights: public DataModule {
#endif

protected:
uint16_t throttle_;
bool breaks_;

// TODO: Accelerometer values
{% for attribute in attributes %}
{{ attribute["type"] }} {{ attribute["name"] }};
{% endfor %}
};

} /* namespace DataModules */
Expand Down
31 changes: 22 additions & 9 deletions datamodule/generate.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import os
import sys
from pathlib import Path
import yaml
from jinja2 import Environment, FileSystemLoader, select_autoescape
from jinja2 import Environment, FileSystemLoader


def main():
config_file = sys.argv[1]

def main(config_file: str):
with open(config_file, "r") as f:
config = yaml.safe_load(f)


env = Environment(loader=FileSystemLoader(os.path.dirname(os.path.abspath(__file__))))
env = Environment(loader=FileSystemLoader(Path(__file__).parent))

cpp_template = env.get_template("cpp/module.cpp")
hpp_template = env.get_template("cpp/module.h")
info_template = env.get_template("cpp/DataModuleInfo.hpp")

for can_message in config["can_messages"]:

# ensure the fist letter is caps
for attribute in can_message["schema"]:
attribute["bytes"] = 2
attribute["name"] = attribute["name"][0].upper() + attribute["name"][1:]

with open(f"{can_message['name']}.cpp", "w") as f:
file = cpp_template.render(
Expand All @@ -27,6 +27,19 @@ def main():
)
f.write(file)

with open(f"{can_message['name']}.hpp", "w") as f:
file = hpp_template.render(
moduleName=can_message["name"],
attributes=can_message["schema"],
)
f.write(file)

with open(f"DataModuleInfo.hpp", "w") as f:
file = info_template.render(
canMessages=config["can_messages"],
)
f.write(file)


if __name__ == "__main__":
main()
main(sys.argv[1])
Empty file added tests/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions tests/goldens/16bit/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
can_messages:
- id: 0x11
name: "RX0"
schema:
- type: "uint16_t"
name: "first"
default: 0

- type: "uint16_t"
name: "second"
default: 0
34 changes: 34 additions & 0 deletions tests/goldens/16bit/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <iostream>
#include <sstream>
#include <cstring>
#include <csignal>
#include "RX0.hpp"

int main() {
uint8_t data[4] = {0x37, 0x44, 0x20, 0x40};
SolarGators::DataModules::RX0 RX0;

RX0.FromByteArray(data);

std::cout << "input first: " << RX0.GetFirstVal() << std::endl;
std::cout << "input second: " << RX0.GetSecondVal() << std::endl;
if (RX0.GetFirstVal() != 0x4437) {
std::cout << "first is wrong!" << std::endl;
return -1;
}

if (RX0.GetSecondVal() != 0x4020) {
std::cout << "second is wrong!" << std::endl;
return -1;
}

RX0.ToByteArray(data);
if (data[0] != 0x37 || data[1] != 0x44) {
std::cout << "first to byte array is wrong!" << std::endl;
return -1;
}
if (data[2] != 0x20 || data[3] != 0x40) {
std::cout << "second to byte array is wrong!" << std::endl;
return -1;
}
}
11 changes: 11 additions & 0 deletions tests/goldens/8bit/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
can_messages:
- id: 0x11
name: "RX0"
schema:
- type: "uint8_t"
name: "first"
default: 0

- type: "uint8_t"
name: "second"
default: 0
34 changes: 34 additions & 0 deletions tests/goldens/8bit/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <iostream>
#include <sstream>
#include <cstring>
#include <csignal>
#include "RX0.hpp"

int main() {
uint8_t data[2] = {0x37, 0x44};
SolarGators::DataModules::RX0 RX0;

RX0.FromByteArray(data);

std::cout << "input first: " << RX0.GetFirstVal() << std::endl;
std::cout << "input second: " << RX0.GetSecondVal() << std::endl;
if (RX0.GetFirstVal() != data[0]) {
std::cout << "first is wrong!" << std::endl;
return -1;
}

if (RX0.GetSecondVal() != data[1]) {
std::cout << "second is wrong!" << std::endl;
return -1;
}

RX0.ToByteArray(data);
if (data[0] != 0x37) {
std::cout << "first to byte array is wrong!" << std::endl;
return -1;
}
if (data[1] != 0x44) {
std::cout << "second to byte array is wrong!" << std::endl;
return -1;
}
}
11 changes: 11 additions & 0 deletions tests/goldens/floats/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
can_messages:
- id: 0x11
name: "RX0"
schema:
- type: "float"
name: "first"
default: 0

- type: "float"
name: "second"
default: 0
Loading