Skip to content
Snippets Groups Projects
Commit 6f3e3e81 authored by Alvise de'Faveri's avatar Alvise de'Faveri
Browse files

[scripts] cleanup and add scxml scripts

Added eventgen.py (event generator based on scxml)
Added scxml2plant script
Modified scripts to be independent to what folder they are called from
Cleanup unused stuff
parent 4e00be53
Branches
Tags
No related merge requests found
Showing
with 883 additions and 986 deletions
# Events Generator Script # Events Generator Script
This script generates Events.h, Topics.h and EventStrings.cpp from a list of This script generates the enums for all Events and Topics handled in a project, given a list of `scxml` files that describe all states and transitions. To execute the script:
SCXML files representing the state machines of a project.
To execute the script: `eventgen.py <LIST_OF_SCXML_FILES>`
`./eventgen.py <LIST_OF_SCXML_FILES>` The header files will be generated in the `generated/` folder.
Note that the SCXML files should contain transitions with the following form: *< TOPIC >.< EVENT >*.
The files will be generated in the generated/ folder.
\ No newline at end of file
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
# #
import re import re
import datetime import datetime
from os.path import join from os.path import join, dirname
import os import os
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
...@@ -32,6 +32,10 @@ from collections import OrderedDict ...@@ -32,6 +32,10 @@ from collections import OrderedDict
OUTPUT_FOLDER = "generated" OUTPUT_FOLDER = "generated"
EVENTS_TEMPLATE_FILE = os.path.dirname(sys.argv[0]) + '/Events.h.template'
TOPICS_TEMPLATE_FILE = os.path.dirname(sys.argv[0]) + '/Topics.h.template'
STRINGS_TEMPLATE_FILE = os.path.dirname(sys.argv[0]) + '/EventStrings.cpp.template'
# #
# ASCII art banner # ASCII art banner
# #
...@@ -106,7 +110,7 @@ def generate_events(events, date): ...@@ -106,7 +110,7 @@ def generate_events(events, date):
event_list_str += e + (", " if e != events[-1] else "") event_list_str += e + (", " if e != events[-1] else "")
# read template # read template
with open('Events.h.template', 'r') as template_file: with open( EVENTS_TEMPLATE_FILE, 'r') as template_file:
template = template_file.read() template = template_file.read()
# write template # write template
...@@ -131,7 +135,7 @@ def generate_topics(topics, date): ...@@ -131,7 +135,7 @@ def generate_topics(topics, date):
topics=t, string='"' + t + '"', endl=endl) topics=t, string='"' + t + '"', endl=endl)
topic_list_str += t + (", " if t != topics[-1] else "") topic_list_str += t + (", " if t != topics[-1] else "")
with open('Topics.h.template', 'r') as template_file: with open( TOPICS_TEMPLATE_FILE, 'r') as template_file:
template = template_file.read() template = template_file.read()
template = template.format(date=date, enum_data=enum_str, topic_list=topic_list_str) template = template.format(date=date, enum_data=enum_str, topic_list=topic_list_str)
...@@ -145,7 +149,7 @@ def generate_topics(topics, date): ...@@ -145,7 +149,7 @@ def generate_topics(topics, date):
# Generate EventFunctions.cpp # Generate EventFunctions.cpp
# #
def generate_functions(event_map_str, topic_map_str, date): def generate_functions(event_map_str, topic_map_str, date):
with open('EventStrings.cpp.template', 'r') as cpp_template_file: with open( STRINGS_TEMPLATE_FILE, 'r') as cpp_template_file:
cpp = cpp_template_file.read() cpp = cpp_template_file.read()
cpp = cpp.format(date=date, event_map_data=event_map_str, topic_map_data=topic_map_str) cpp = cpp.format(date=date, event_map_data=event_map_str, topic_map_data=topic_map_str)
......
#!/bin/bash #!/bin/bash
#
# Usage: grepcheck <FOLDER_TO_CHECK> <STRING_TO_FIND> <EGREP_ARGS>
#
function grepcheck {
FILES=$(grep -rl "$2" $1 | egrep "$3")
for f in $FILES
do
# Print name of the file in red
echo -ne '\033\x5b\x33\x33\x6d'
echo $f
echo -ne '\033\x5b\x30\x6d'
if [[ $verbose -eq 1 ]]; then
grep --color=always -r "$2" $f -C3
echo ''
fi
done
echo ''
# If VERBOSE is defined then also print the context in the file
}
# Horrifying way of checking if -v or --verbose is enabled
verbose=0
case "$1" in
-v|--verbose)
verbose=1
shift ;;
esac
case "$2" in
-v|--verbose)
verbose=1
esac
# Execute checks
echo '--------------------------- CPPCHECK'
echo '[Linter] Executing cppcheck' echo '[Linter] Executing cppcheck'
cppcheck --template=gcc -q --std=c++11 --enable=all \ echo ''
cppcheck -U "RCC_APB1ENR_CAN2EN" --template=gcc -q --std=c++11 --enable=all \
--suppress=unusedFunction --suppress=missingInclude --suppress=noExplicitConstructor \ --suppress=unusedFunction --suppress=missingInclude --suppress=noExplicitConstructor \
"$@" 2>&1 | awk ' "$1" 2>&1 | awk '
function color(c,s) { function color(c,s) {
printf("\033[%dm%s\033[0m\n",30+c,s) printf("\033[%dm%s\033[0m\n",30+c,s)
} }
/warning/ {color(1,$0);next} /error/ {color(1,$0);next}
/warning/ {color(3,$0);next}
/style/ {color(2,$0);next} /style/ {color(2,$0);next}
/performance/ {color(3,$0);next} /performance/ {color(6,$0);next}
/information/ {color(4,$0);next} /information/ {color(4,$0);next}
/portability/ {color(5,$0);next} /portability/ {color(5,$0);next}
{print} {print}
' '
echo ''
echo '--------------------------- USING NAMESPACE'
echo '[Linter] Checking for using namespace in .h(pp) files'
grepcheck $1 'using namespace' '.h(pp)?$'
echo '--------------------------- GREP PRINTF'
echo '[Linter] Checking for printf instead of TRACE'
grepcheck $1 "printf" '.*'
echo '--------------------------- GREP ASSERT'
echo '[Linter] Checking if there are asserts in the code'
grepcheck $1 "assert" '.*'
echo '--------------------------- GREP THROW'
echo '[Linter] Checking if there are exceptions in the code'
grepcheck $1 "throw" '~*catch.hpp'
#exit 0 #exit 0
# Mavlink Clinet # Mavlink Client
These scripts can be used to transmit and receive mavlink data from a PC, either These scripts can be used to transmit and receive mavlink data from a PC, either
connected via serial port to a transceiver or directly connected to one of the boards. connected via serial port to a transceiver or directly connected to one of the boards.
`make` compiles the 3 `.c` files: Use `make` to compile the 3 `.c` files:
* continuous_tx: sends a message of raw bytes with a given length at a certain * continuous_tx: sends a message of raw bytes with a given length at a certain
frequency. This was used to test the LoRa modules. frequency. This was used to test the LoRa modules.
* mavlink_demo_tx: sends a message whenever it receives a char on stdin * mavlink_demo_tx: sends a message whenever it receives a char on stdin
* mavlink_demo_rx: receives and prints packets, eventually sending back ana ACK. * mavlink_demo_rx: receives and prints packets, eventually sending back an ACK.
`plot.py`: reads value on stdin and plots them. Can be used piping in the output `plot.py`: reads value on stdin and plots them. Can be used piped with the output
of mavlink_demo_rx of mavlink_demo_rx.
\ No newline at end of file \ No newline at end of file
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Usage: $0 <filename.bin>"
exit -1
fi;
stm32flash -b 500000 -w $1 -v /dev/ttyUSB0
client
all:
gcc -o client client.c -lcurses
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <ncurses.h>
#include <signal.h>
#include <stdint.h>
#include <termios.h>
#include <unistd.h>
volatile int stop = 0;
uint8_t buf[8192] = {0};
uint16_t rptr = 0, wptr = 0;
#pragma pack(1)
struct vec3_t {
float x;
float y;
float z;
};
#pragma pack()
enum DataType
{
DATA_VEC3 = 0,
DATA_QUAT = 1,
DATA_FLOAT = 2,
DATA_INT = 3,
DATA_STRING= 4,
DATA_LIMITED_INT = 5,
DATA_UINT32 = 6
};
const char* sensor_names[] =
{
"ACCEL_MPU9250",
"ACCEL_INEMO",
"ACCEL_MAX21105",
"GYRO_MPU9250",
"GYRO_INEMO",
"GYRO_FXAS21002",
"GYRO_MAX21105",
"COMPASS_MPU9250",
"COMPASS_INEMO",
"TEMP_MPU9250",
"TEMP_INEMO",
"TEMP_LPS331AP",
"TEMP_MAX21105",
"TEMP_MS580",
"PRESS_LPS331AP",
"PRESS_MS580",
"UNUSED_16",
"DMA_TX_FIFOSZ",
"DMA_RX_FIFOSZ",
"DMA_FIFO_ERR",
"CPU%",
"LOG_QUEUE_SZ"
};
uint8_t sensor_type[] =
{
DATA_VEC3,
DATA_VEC3,
DATA_VEC3,
DATA_VEC3,
DATA_VEC3,
DATA_VEC3,
DATA_VEC3,
DATA_VEC3,
DATA_VEC3,
DATA_FLOAT,
DATA_FLOAT,
DATA_FLOAT,
DATA_FLOAT,
DATA_FLOAT,
DATA_FLOAT,
DATA_FLOAT,
DATA_INT,
DATA_LIMITED_INT,
DATA_LIMITED_INT,
DATA_UINT32,
DATA_UINT32,
DATA_LIMITED_INT
};
#define NUM_SENSORS ((int)((sizeof(sensor_names) / sizeof(sensor_names[0]))))
void on_signal(int s)
{
if(!stop)
{
signal(s, on_signal);
stop = 1;
}
}
int logline = 0;
void log_string(const char* data, int len)
{
if(len <= 0)
return;
move(NUM_SENSORS + 2 + logline, 10);
attron(COLOR_PAIR(1));
printw(data);
if(len < 30)
for(int i=len;i<30;i++)
printw(" ");
refresh();
logline = (logline+1)%20;
}
void draw_sensor(int id, int type, const void* data)
{
char tmp[256] = {0};
if(id >= (int)NUM_SENSORS)
{
sprintf(tmp, "Got packet for invalid sensor %d\n", id);
log_string(tmp, strlen(tmp));
return;
}
if(type < 0 || type > 6 || type == 4)
{
sprintf(tmp, "Got packet for invalid type %d\n", type);
log_string(tmp, strlen(tmp));
return;
}
move(1+id, 10);
sprintf(tmp, "%20s : ", sensor_names[id]);
uint8_t color = (type != 5) ? (type + 1) : 2;
attron(COLOR_PAIR(color));
printw(tmp);
attroff(COLOR_PAIR(color));
int all_null = 1;
for(int i=0;i<NUM_SENSORS && all_null == 1;i++)
if(((const char *)data)[i] != 0)
all_null = 0;
if((data == NULL || all_null == 1) && type != 5)
{
attron(COLOR_PAIR(5));
attron(A_BOLD);
printw("[NULL] ");
attroff(A_BOLD);
attroff(COLOR_PAIR(5));
return;
}
const uint8_t* i = (const uint8_t*) data;
const struct vec3_t* v = (const struct vec3_t*) data;
const float* f = (const float*) data;
const uint8_t* ui = (const uint8_t*) data;
const uint32_t* ui32 = (const uint32_t*) data;
switch(type)
{
case DATA_FLOAT:
sprintf(tmp, "%7.4f ", *f);
printw(tmp);
break;
case DATA_INT:
sprintf(tmp, "%d ", *i);
printw(tmp);
break;
case DATA_UINT32:
sprintf(tmp, "%d ", *ui32);
printw(tmp);
break;
case DATA_VEC3:
sprintf(tmp, "(%7.4f, %7.4f, %7.4f)", v->x, v->y, v->z);
printw(tmp);
break;
case DATA_LIMITED_INT:
{
uint32_t vv = (*ui * 27) / 256;
for(uint32_t i=0;i<27;i++)
{
if(i < vv)
printw("#");
else
printw(".");
}
break;
}
default:
printw("[NOT IMPLEMENTED]");
break;
}
}
int sfd;
int init_serial(const char *device)
{
sfd = open(device, O_RDWR | O_NOCTTY | O_SYNC);
if(sfd < 0)
{
printf("Cannot open ttyUSB0\n");
return 1;
}
struct termios tty;
memset(&tty, 0, sizeof(tty));
if(tcgetattr(sfd, &tty) != 0)
{
printf("Cannot get attributes\n");
return 1;
}
cfmakeraw(&tty);
cfsetospeed(&tty, B115200);
cfsetispeed(&tty, B115200);
tcsetattr(sfd, TCSANOW, &tty);
return 0;
}
void parse(int len)
{
if(len == 0)
return;
uint8_t type = buf[0];
if(type == DATA_STRING)
log_string((const char *)&buf[1], len-1);
else
{
uint8_t id = buf[1];
draw_sensor(id, type, &buf[2]);
}
}
int fromHex(char l)
{
if(l >= '0' && l <= '9')
return l - '0';
if(l >= 'a' && l <= 'f')
return 10 + l - 'a';
if(l >= 'A' && l <= 'F')
return 10 + l - 'A';
return 0;
}
int read_and_draw()
{
memset(buf, 0, sizeof(buf));
int bpos = 0;
char b;
char tmp = 0;
do {
read(sfd, &b, 1);
if(b == '\n' || b == '\r')
break;
else {
if(tmp == 0)
tmp = b;
else {
buf[bpos++] = (fromHex(tmp) << 4) | fromHex(b);
tmp = 0;
}
}
} while(1);
parse(bpos);
return 0;
}
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("Usage: %s <PORT>\n", argv[0]);
return -1;
}
if(init_serial(argv[1]))
return -1;
signal(SIGINT, on_signal);
signal(SIGTERM, on_signal);
initscr();
start_color();
init_pair(1, COLOR_BLUE, COLOR_BLACK);
init_pair(2, COLOR_GREEN, COLOR_BLACK);
init_pair(3, COLOR_CYAN, COLOR_BLACK);
init_pair(4, COLOR_WHITE, COLOR_BLACK);
init_pair(5, COLOR_RED, COLOR_BLACK);
init_pair(7, COLOR_MAGENTA, COLOR_BLACK);
erase();
refresh();
log_string("Ready...", 8);
while(!stop)
{
if(read_and_draw() == 1)
stop = 1;
refresh();
}
endwin();
signal(SIGINT, 0);
signal(SIGTERM, 0);
return 0;
}
/* Copyright (c) 2018 Skyward Experimental Rocketry
* Authors: Luca Erbetta
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
******************************************************************************
* THIS FILE IS AUTOGENERATED. DO NOT EDIT. *
******************************************************************************
*/
// Generated from: {sheet_link}
// Autogen date: {date}
#include "Events.h"
#include "Topics.h"
#include <map>
namespace HomeoneBoard
{{
string getEventString(uint8_t event)
{{
static const map<uint8_t, string> event_string_map {{
{event_map_data}
}};
auto it = event_string_map.find(event);
return it == event_string_map.end() ? "EV_UNKNOWN" : it->second;
}}
string getTopicString(uint8_t topic)
{{
static const map<uint8_t, string> topic_string_map{{
{topic_map_data}
}};
auto it = topic_string_map.find(topic);
return it == topic_string_map.end() ? "TOPIC_UNKNOWN" : it->second;
}}
}}
\ No newline at end of file
/* Copyright (c) 2018 Skyward Experimental Rocketry
* Authors: Luca Erbetta
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
******************************************************************************
* THIS FILE IS AUTOGENERATED. DO NOT EDIT. *
******************************************************************************
*/
// Generated from: {sheet_link}
// Autogen date: {date}
#ifndef SRC_SHARED_BOARDS_HOMEONE_EVENTS_H
#define SRC_SHARED_BOARDS_HOMEONE_EVENTS_H
#include <cstdint>
#include <string>
#include "events/Event.h"
#include "events/EventBroker.h"
#include "EventClasses.h"
#include "Topics.h"
using std::string;
using std::map;
namespace HomeoneBoard
{{
/**
* Definition of all events in the Homeone Board software
* Refer to section 5.1.1 of the Software Design Document.
*/
enum Events : uint8_t
{{
{enum_data}
}};
/**
* @brief Returns the name of the provided event
*
* @param event
* @return string
*/
string getEventString(uint8_t event);
}}
#endif /* SRC_SHARED_BOARDS_HOMEONE_EVENTS_H */
# Events Generator Script
This script generates the Events.h and Topics.h heander file from a GoogleSheets document on Google Drive.
To execute the script:
```
pip install --upgrade google-api-python-client
pip install oauth2client
python scripts/homeone/event_header_generator/event_generator.py
```
The first time a browser window should open asking for your credentials (use the Skyward ones).
If it doesn't and only gives you an error, try executing it by clicking on the icon.
\ No newline at end of file
/* Copyright (c) 2018 Skyward Experimental Rocketry
* Authors: Luca Erbetta
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
******************************************************************************
* THIS FILE IS AUTOGENERATED. DO NOT EDIT. *
******************************************************************************
*/
// Generated from: {sheet_link}
// Autogen date: {date}
#ifndef SRC_SHARED_BOARDS_HOMEONE_TOPICS_H
#define SRC_SHARED_BOARDS_HOMEONE_TOPICS_H
#include <stdint.h>
#include <string>
using std::map;
using std::string;
namespace HomeoneBoard
{{
/**
* Definition of various event topics to use in the EventBroker
*/
enum Topics : uint8_t
{{
{enum_data}
}};
/**
* @brief Returns the name of the provided event
*
* @param event
* @return string
*/
string getTopicString(uint8_t topic);
}} // namespace HomeoneBoard
#endif /* SRC_SHARED_BOARDS_HOMEONE_TOPICS_H_ */
{"installed":{"client_id":"1025168905991-tv31etsgm3lecodc5c798shqciekad40.apps.googleusercontent.com","project_id":"homeone-event-ge-1540834105298","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://www.googleapis.com/oauth2/v3/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"Yhaf67HuHR4DyXZKNXWu2lre","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
\ No newline at end of file
#!/usr/bin/python3
# Copyright (c) 2018 Skyward Experimental Rocketry
# Authors: Luca Erbetta
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
import re
import datetime
import sys
from os.path import join
import os
OUTPUT_FOLDER = "generated"
SCOPES = 'https://www.googleapis.com/auth/spreadsheets.readonly'
service = None
SPREADSHEET_ID = '12TecOmDd7Uot-MvXkCbhDJRU48-XO6s5ChKDlr4AOvI'
EVENTS_RANGE_NAME = 'EventList!A2:A'
TOPICS_RANGE_NAME = 'Topics!B3:B'
def auth():
try:
store = file.Storage('store.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
global service
service = build('sheets', 'v4', http=creds.authorize(Http()))
return True
except:
print("Authentication error:", sys.exc_info()[0])
return False
def load_events():
result = service.spreadsheets().values().get(spreadsheetId=SPREADSHEET_ID,
range=EVENTS_RANGE_NAME).execute()
lines = result.get('values', [])
# Event names start with EV_ and contains only uppercase letters or underscores
re_event = re.compile(r'(?P<ev>^EV_([A-Z_]+)+)')
# Only return lines with valid events, remove additional data
events = []
for l in lines:
m = re_event.match(l[0])
if m is not None:
events.append(m.group('ev'))
else:
print("Skipped line containing invalid event: {}".format(l))
return events
def load_topics():
result = service.spreadsheets().values().get(spreadsheetId=SPREADSHEET_ID,
range=TOPICS_RANGE_NAME).execute()
lines = result.get('values', [])
re_topics = re.compile(r'(?P<topic>^TOPIC_([A-Z_]+)+)')
# Only return lines with valid topics, remove additional data
topics = []
for l in lines:
m = re_topics.match(l[0])
if m is not None:
topics.append(m.group('topic'))
else:
print("Skipped line containing invalid topics: {}".format(l))
return topics
def has_duplicates(lst):
if len(lst) != len(set(lst)):
return True
return False
print("Homeone on-board software event header generator v0.2")
print("Google sheets API auth in progress...")
if auth():
print("Auth successfull.")
else:
exit()
#directory = os.path.dirname(OUTPUT_FOLDER)
if not os.path.exists(OUTPUT_FOLDER):
os.mkdir(OUTPUT_FOLDER)
print("Reading from: https://docs.google.com/spreadsheets/d/12TecOmDd7Uot-MvXkCbhDJRU48-XO6s5ChKDlr4AOvI")
events = load_events()
topics = load_topics()
# Check duplicates
if has_duplicates(events):
print("Duplicate events found! Terminating.")
exit()
if has_duplicates(topics):
print("Duplicate topics found! Terminating.")
exit()
print("{} events loaded.".format(len(events)))
print("{} topics loaded.".format(len(topics)))
enum_str = ""
event_map_str = ""
date = datetime.datetime.now()
link = "https://docs.google.com/spreadsheets/d/{id}".format(id=SPREADSHEET_ID)
# Events.h generation
print("Generating Events.h...")
for e in events:
endl = ",\n" if e != events[-1] else ""
enum_str += " " + e + \
(" = EV_FIRST_SIGNAL" if e == events[0] else "") + endl
event_map_str += " {{ {event}, {string} }}{endl}".format(
event=e, string='"' + e + '"', endl=endl)
with open('Events.h.template', 'r') as template_file:
template = template_file.read()
template = template.format(sheet_link=link, date=date,
enum_data=enum_str)
with open(join(OUTPUT_FOLDER, 'Events.h'), 'w') as header_file:
header_file.write(template)
print("Events.h successfully generated.")
# Topics.h generation
print("Generating Topics.h...")
enum_str = ""
topic_map_str = ""
for t in topics:
endl = ",\n" if t != topics[-1] else ""
enum_str += " " + t + endl
topic_map_str += " {{ {topics}, {string} }}{endl}".format(
topics=t, string='"' + t + '"', endl=endl)
with open('Topics.h.template', 'r') as template_file:
template = template_file.read()
template = template.format(sheet_link=link, date=date,
enum_data=enum_str)
with open(join(OUTPUT_FOLDER, 'Topics.h'), 'w') as header_file:
header_file.write(template)
with open('EventFunctions.cpp.template', 'r') as cpp_template_file:
cpp = cpp_template_file.read()
cpp = cpp.format(sheet_link=link, date=date,
event_map_data=event_map_str, topic_map_data=topic_map_str)
with open(join(OUTPUT_FOLDER, 'EventFunctions.cpp'), 'w') as cpp_file:
cpp_file.write(cpp)
print("Topics.h successfully generated.")
print()
print("All files successfully generated. Please move Events.h, Topics.h, EventFunction.cpp into the Homeone board folder.")
print(".... Done.")
#!/usr/bin/python
# Copyright (c) 2017 Skyward Experimental Rocketry
# Authors: Alain Carlucci
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import csv,string,hashlib,datetime,sys
if len(sys.argv) != 3:
print("Usage: %s <CSV File> <Output header file>" % (sys.argv[0]))
exit(-1)
headerLine = None
newLines = []
lineCtr = 0
curCatId = 0
categories={}
enums={}
import hashlib
def fileHash(filename):
h = hashlib.sha1()
with open(filename, 'rb', buffering=0) as f:
for b in iter(lambda : f.read(128*1024), b''):
h.update(b)
return h.hexdigest()
def genEnum(name, s, inc):
a = ('''enum class %s
{
''') % (name,);
cnt = 0
for i in s:
if inc:
a += " " + i + " = " + str(cnt) + ",\n"
else:
a += " " + i + " = " + str(s[i]) + ",\n"
cnt += 1
a += "};\n"
a += "const std::size_t %s_SIZE = %d;\n" %(name, cnt)
return a
def genHeaderFile(fileName,csvFile):
print("[*] Generating header file (%s)" %(fileName,))
content = ('''/* Copyright (c) 2017 Skyward Experimental Rocketry
* Authors: Alain Carlucci
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
******************************************************************************
* THIS FILE IS AUTOGENERATED. DO NOT EDIT. *
******************************************************************************
*/
// CSV File: %s
// SHA1 of CSV File: %s
// Autogen date: %s
#include <cstdint>
#ifndef SKYWARD_FAULT_CTRL_LIST_H
#define SKYWARD_FAULT_CTRL_LIST_H
''') % (csvFile, fileHash(csvFile), datetime.datetime.now())
content += genEnum("Fault", enums, True)
content += "\nnamespace FaultCounterData\n{\n\n"
content += genEnum("FaultCategory", categories, False)
content += '''
// Usage: categoryID = FaultCounter::FaultToCategory[faultID];
const uint32_t FaultToCategory[] =
{
'''
colCnt = 0
for i in enums:
content += "%d, " % (categories[enums[i]], )
colCnt += 1
if colCnt == 20:
content += "\n "
colCnt = 0
content += '''
}; /* CategoryMapping */
} /* FaultCounterData */
#endif /* SKYWARD_FAULT_CTRL_LIST_H */
'''
try:
with open(fileName, "w") as f:
f.write(content)
print("[+] Written %d lines in %s" % (len(content.split("\n")), fileName))
except:
print("[!] Cannot open %s for writing.", fileName)
exit(-1)
def checkForGoodName(n):
if len(n) == 0:
return False
if n[0] not in string.ascii_uppercase:
return False
for x in n:
if x not in string.ascii_uppercase + string.digits + '_':
return False
if n[-1] not in string.ascii_uppercase + string.digits:
return False
return True
def genEnumName(cat,name):
ctr = 2
genBName = "F_" + cat + "_" + name
genName = genBName
while genName in enums:
genName = genBName + "_" + str(ctr)
ctr += 1
return genName
# return False: csv file is ok
# return True: csv file must be updated
def handleLine(r):
global lineCtr,categories,newLines,enums,curCatId
if len(r) != 4:
print("[!] Parsing error at line %d. I'm expecting 4 fields" % (lineCtr,))
exit(-1)
curCat = r[0].strip().upper()
curName = r[1].strip().upper()
curDesc = r[2].strip()
curEnum = r[3].strip().upper()
if checkForGoodName(curCat) == False:
print("[!] Invalid category at line %d." % (lineCtr,))
exit(-1)
if checkForGoodName(curName) == False:
print("[!] Invalid name at line %d." % (lineCtr,))
exit(-1)
if len(curEnum) > 0 and (checkForGoodName(curEnum) == False or curEnum in enums):
print("[!] Invalid generated name at line %d." % (lineCtr,))
exit(-1)
retVal = False
if len(curEnum) == 0:
curEnum = genEnumName(curCat, curName)
retVal = True
if curCat not in categories:
print("[+] Added category '%s'" % (curCat,))
categories[curCat] = curCatId
curCatId += 1
print("[+] Added %s in category %s" %(curEnum,curCat))
enums[curEnum] = curCat
newLines.append([curCat, curName, curDesc, curEnum])
return retVal
mustUpdate = False
print("[*] Opening %s..." % (sys.argv[1],))
try:
with open(sys.argv[1], "r") as csvfile:
r = csv.reader(csvfile, delimiter=',', quotechar='"')
for row in r:
lineCtr += 1
if headerLine is None:
headerLine = row
continue
if handleLine(row):
mustUpdate = True
except Exception as e:
print("[!] Cannot open %s for reading: %s!" %(sys.argv[1],str(e)))
exit(-1)
if not mustUpdate:
print("[+] No need to update the csv file.")
else:
print("[*] Updating %s..." % (sys.argv[1],))
try:
with open(sys.argv[1], "w") as csvfile:
r = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
r.writerow(headerLine)
for row in newLines:
r.writerow(row)
print("[+] Successfully updated csv file")
except:
print("[!] Cannot open %s for writing!" %(sys.argv[1],))
exit(-1)
genHeaderFile(sys.argv[2], sys.argv[1])
File moved
File moved
#!/bin/bash
# Input checks
if [ "$#" -ne 1 ]; then
echo "Usage: scxml2plant <FOLDER_TO_SEARCH>"
exit 1
fi
# Find this folder when calling the script from another folder
PATH_TO_XALAN=$(dirname $0)
# Select all scxml files
for file in $(find $1 -name "*.scxml")
do
# generate plantuml
INPUT_XML=$file
OUTPUT_NAME=$(dirname $file)/$(basename -s ".scxml" $file).plantuml
echo "Input file: " $INPUT_XML " Output basename: " $OUTPUT_NAME
java -cp $PATH_TO_XALAN/xalan/xalan.jar \
-Dorg.apache.xerces.xni.parser.XMLParserConfiguration=org.apache.xerces.parsers.XIncludeParserConfiguration org.apache.xalan.xslt.Process \
-IN $INPUT_XML -XSL $PATH_TO_XALAN/xslt/scxml2plantuml.xslt -OUT $OUTPUT_NAME
# generate README
README_FILE=$(dirname $file)/README.md
touch $README_FILE
echo "\`\`\`plantuml" > $README_FILE
cat $OUTPUT_NAME >> $README_FILE
echo "\`\`\`" >> $README_FILE
rm $OUTPUT_NAME
done
This diff is collapsed.
=========================================================================
== NOTICE file corresponding to section 4(d) of the Apache License, ==
== Version 2.0, in this case for the Apache Xalan Java distribution. ==
=========================================================================
Apache Xalan (Xalan XSLT processor)
Copyright 1999-2014 The Apache Software Foundation
Apache Xalan (Xalan serializer)
Copyright 1999-2012 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
=========================================================================
Portions of this software was originally based on the following:
- software copyright (c) 1999-2002, Lotus Development Corporation.,
http://www.lotus.com.
- software copyright (c) 2001-2002, Sun Microsystems.,
http://www.sun.com.
- software copyright (c) 2003, IBM Corporation.,
http://www.ibm.com.
=========================================================================
The binary distribution package (ie. jars, samples and documentation) of
this product includes software developed by the following:
- The Apache Software Foundation
- Xerces Java - see LICENSE.txt
- JAXP 1.3 APIs - see LICENSE.txt
- Bytecode Engineering Library - see LICENSE.txt
- Regular Expression - see LICENSE.txt
- Scott Hudson, Frank Flannery, C. Scott Ananian
- CUP Parser Generator runtime (javacup\runtime) - see LICENSE.txt
=========================================================================
The source distribution package (ie. all source and tools required to build
Xalan Java) of this product includes software developed by the following:
- The Apache Software Foundation
- Xerces Java - see LICENSE.txt
- JAXP 1.3 APIs - see LICENSE.txt
- Bytecode Engineering Library - see LICENSE.txt
- Regular Expression - see LICENSE.txt
- Ant - see LICENSE.txt
- Stylebook doc tool - see LICENSE.txt
- Elliot Joel Berk and C. Scott Ananian
- Lexical Analyzer Generator (JLex) - see LICENSE.txt
=========================================================================
Apache Xerces Java
Copyright 1999-2006 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
Portions of Apache Xerces Java in xercesImpl.jar and xml-apis.jar
were originally based on the following:
- software copyright (c) 1999, IBM Corporation., http://www.ibm.com.
- software copyright (c) 1999, Sun Microsystems., http://www.sun.com.
- voluntary contributions made by Paul Eng on behalf of the
Apache Software Foundation that were originally developed at iClick, Inc.,
software copyright (c) 1999.
=========================================================================
Apache xml-commons xml-apis (redistribution of xml-apis.jar)
Apache XML Commons
Copyright 2001-2003,2006 The Apache Software Foundation.
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
Portions of this software were originally based on the following:
- software copyright (c) 1999, IBM Corporation., http://www.ibm.com.
- software copyright (c) 1999, Sun Microsystems., http://www.sun.com.
- software copyright (c) 2000 World Wide Web Consortium, http://www.w3.org
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment