mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 16:29:04 -06:00
Moved GSE dictionaries to deployment directory, moved Gse binaries to Gds/tkGui/bin
This commit is contained in:
parent
33c39c94a0
commit
e74f575ae7
3
.gitignore
vendored
3
.gitignore
vendored
@ -61,3 +61,6 @@ core
|
||||
*TopologyAppAi_IDTableLog.txt
|
||||
|
||||
.vscode
|
||||
py_dict
|
||||
.settings
|
||||
|
||||
|
||||
@ -290,7 +290,7 @@ def generate_topology(the_parsed_topology_xml, xml_filename, opt):
|
||||
# Hack to set up deployment path for instanced dictionaries (if one exists remove old one)
|
||||
#
|
||||
if opt.default_topology_dict:
|
||||
os.environ["DICT_DIR"] = os.environ.get("FPRIME_CORE_DIR", BUILD_ROOT) + os.sep + "Gse/generated" + os.sep + DEPLOYMENT
|
||||
os.environ["DICT_DIR"] = os.environ.get("FPRIME_CORE_DIR", BUILD_ROOT) + os.sep + DEPLOYMENT + os.sep + "py_dict"
|
||||
dict_dir = os.environ["DICT_DIR"]
|
||||
PRINT.info("Removing old instanced topology dictionaries in: %s", dict_dir)
|
||||
import shutil
|
||||
|
||||
@ -8,25 +8,25 @@ XML Source: ${source}
|
||||
'''
|
||||
|
||||
# Import the types this way so they do not need prefixing for execution.
|
||||
from fprime.gse.models.serialize.type_exceptions import *
|
||||
from fprime.gse.models.serialize.type_base import *
|
||||
from fprime.common.models.serialize.type_exceptions import *
|
||||
from fprime.common.models.serialize.type_base import *
|
||||
|
||||
from fprime.gse.models.serialize.bool_type import *
|
||||
from fprime.gse.models.serialize.enum_type import *
|
||||
from fprime.gse.models.serialize.f32_type import *
|
||||
from fprime.gse.models.serialize.f64_type import *
|
||||
from fprime.common.models.serialize.bool_type import *
|
||||
from fprime.common.models.serialize.enum_type import *
|
||||
from fprime.common.models.serialize.f32_type import *
|
||||
from fprime.common.models.serialize.f64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.u8_type import *
|
||||
from fprime.gse.models.serialize.u16_type import *
|
||||
from fprime.gse.models.serialize.u32_type import *
|
||||
from fprime.gse.models.serialize.u64_type import *
|
||||
from fprime.common.models.serialize.u8_type import *
|
||||
from fprime.common.models.serialize.u16_type import *
|
||||
from fprime.common.models.serialize.u32_type import *
|
||||
from fprime.common.models.serialize.u64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.i8_type import *
|
||||
from fprime.gse.models.serialize.i16_type import *
|
||||
from fprime.gse.models.serialize.i32_type import *
|
||||
from fprime.gse.models.serialize.i64_type import *
|
||||
from fprime.common.models.serialize.i8_type import *
|
||||
from fprime.common.models.serialize.i16_type import *
|
||||
from fprime.common.models.serialize.i32_type import *
|
||||
from fprime.common.models.serialize.i64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.string_type import *
|
||||
from fprime.gse.models.serialize.serializable_type import *
|
||||
from fprime.common.models.serialize.string_type import *
|
||||
from fprime.common.models.serialize.serializable_type import *
|
||||
|
||||
from fprime.gse.models.common import channel_telemetry
|
||||
from fprime.common.models.common import channel_telemetry
|
||||
|
||||
@ -8,25 +8,25 @@ XML Source: ${source}
|
||||
'''
|
||||
|
||||
# Import the types this way so they do not need prefixing for execution.
|
||||
from fprime.gse.models.serialize.type_exceptions import *
|
||||
from fprime.gse.models.serialize.type_base import *
|
||||
from fprime.common.models.serialize.type_exceptions import *
|
||||
from fprime.common.models.serialize.type_base import *
|
||||
|
||||
from fprime.gse.models.serialize.bool_type import *
|
||||
from fprime.gse.models.serialize.enum_type import *
|
||||
from fprime.gse.models.serialize.f32_type import *
|
||||
from fprime.gse.models.serialize.f64_type import *
|
||||
from fprime.common.models.serialize.bool_type import *
|
||||
from fprime.common.models.serialize.enum_type import *
|
||||
from fprime.common.models.serialize.f32_type import *
|
||||
from fprime.common.models.serialize.f64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.u8_type import *
|
||||
from fprime.gse.models.serialize.u16_type import *
|
||||
from fprime.gse.models.serialize.u32_type import *
|
||||
from fprime.gse.models.serialize.u64_type import *
|
||||
from fprime.common.models.serialize.u8_type import *
|
||||
from fprime.common.models.serialize.u16_type import *
|
||||
from fprime.common.models.serialize.u32_type import *
|
||||
from fprime.common.models.serialize.u64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.i8_type import *
|
||||
from fprime.gse.models.serialize.i16_type import *
|
||||
from fprime.gse.models.serialize.i32_type import *
|
||||
from fprime.gse.models.serialize.i64_type import *
|
||||
from fprime.common.models.serialize.i8_type import *
|
||||
from fprime.common.models.serialize.i16_type import *
|
||||
from fprime.common.models.serialize.i32_type import *
|
||||
from fprime.common.models.serialize.i64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.string_type import *
|
||||
from fprime.gse.models.serialize.serializable_type import *
|
||||
from fprime.common.models.serialize.string_type import *
|
||||
from fprime.common.models.serialize.serializable_type import *
|
||||
|
||||
from fprime.gse.models.common import command
|
||||
from fprime.common.models.common import command
|
||||
|
||||
@ -8,25 +8,25 @@ XML Source: ${source}
|
||||
'''
|
||||
|
||||
# Import the types this way so they do not need prefixing for execution.
|
||||
from fprime.gse.models.serialize.type_exceptions import *
|
||||
from fprime.gse.models.serialize.type_base import *
|
||||
from fprime.common.models.serialize.type_exceptions import *
|
||||
from fprime.common.models.serialize.type_base import *
|
||||
|
||||
from fprime.gse.models.serialize.bool_type import *
|
||||
from fprime.gse.models.serialize.enum_type import *
|
||||
from fprime.gse.models.serialize.f32_type import *
|
||||
from fprime.gse.models.serialize.f64_type import *
|
||||
from fprime.common.models.serialize.bool_type import *
|
||||
from fprime.common.models.serialize.enum_type import *
|
||||
from fprime.common.models.serialize.f32_type import *
|
||||
from fprime.common.models.serialize.f64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.u8_type import *
|
||||
from fprime.gse.models.serialize.u16_type import *
|
||||
from fprime.gse.models.serialize.u32_type import *
|
||||
from fprime.gse.models.serialize.u64_type import *
|
||||
from fprime.common.models.serialize.u8_type import *
|
||||
from fprime.common.models.serialize.u16_type import *
|
||||
from fprime.common.models.serialize.u32_type import *
|
||||
from fprime.common.models.serialize.u64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.i8_type import *
|
||||
from fprime.gse.models.serialize.i16_type import *
|
||||
from fprime.gse.models.serialize.i32_type import *
|
||||
from fprime.gse.models.serialize.i64_type import *
|
||||
from fprime.common.models.serialize.i8_type import *
|
||||
from fprime.common.models.serialize.i16_type import *
|
||||
from fprime.common.models.serialize.i32_type import *
|
||||
from fprime.common.models.serialize.i64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.string_type import *
|
||||
from fprime.gse.models.serialize.serializable_type import *
|
||||
from fprime.common.models.serialize.string_type import *
|
||||
from fprime.common.models.serialize.serializable_type import *
|
||||
|
||||
from fprime.gse.models.common import event
|
||||
from fprime.common.models.common import event
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
|
||||
# Import the types this way so they do not need prefixing for execution.
|
||||
from fprime.gse.models.serialize.type_exceptions import *
|
||||
from fprime.gse.models.serialize.type_base import *
|
||||
from fprime.common.models.serialize.type_exceptions import *
|
||||
from fprime.common.models.serialize.type_base import *
|
||||
|
||||
from fprime.gse.models.serialize.bool_type import *
|
||||
from fprime.gse.models.serialize.enum_type import *
|
||||
from fprime.gse.models.serialize.f32_type import *
|
||||
from fprime.gse.models.serialize.f64_type import *
|
||||
from fprime.common.models.serialize.bool_type import *
|
||||
from fprime.common.models.serialize.enum_type import *
|
||||
from fprime.common.models.serialize.f32_type import *
|
||||
from fprime.common.models.serialize.f64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.u8_type import *
|
||||
from fprime.gse.models.serialize.u16_type import *
|
||||
from fprime.gse.models.serialize.u32_type import *
|
||||
from fprime.gse.models.serialize.u64_type import *
|
||||
from fprime.common.models.serialize.u8_type import *
|
||||
from fprime.common.models.serialize.u16_type import *
|
||||
from fprime.common.models.serialize.u32_type import *
|
||||
from fprime.common.models.serialize.u64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.i8_type import *
|
||||
from fprime.gse.models.serialize.i16_type import *
|
||||
from fprime.gse.models.serialize.i32_type import *
|
||||
from fprime.gse.models.serialize.i64_type import *
|
||||
from fprime.common.models.serialize.i8_type import *
|
||||
from fprime.common.models.serialize.i16_type import *
|
||||
from fprime.common.models.serialize.i32_type import *
|
||||
from fprime.common.models.serialize.i64_type import *
|
||||
|
||||
from fprime.gse.models.serialize.string_type import *
|
||||
from fprime.gse.models.serialize.serializable_type import *
|
||||
from fprime.common.models.serialize.string_type import *
|
||||
from fprime.common.models.serialize.serializable_type import *
|
||||
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
Cheetah
|
||||
enum34
|
||||
lxml
|
||||
Markdown
|
||||
multiprocess
|
||||
pexpect
|
||||
Pmw
|
||||
wxPython
|
||||
@ -1,525 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#===============================================================================
|
||||
# NAME: tinyseqgen
|
||||
#
|
||||
# DESCRIPTION: A tiny sequence generator for F Prime. This sequence compiler takes a
|
||||
# .seq file as input and produces a binary sequence file compatible with the
|
||||
# F Prime sequence file loader and sequence file runner.
|
||||
# AUTHOR: Kevin Dinkel
|
||||
# EMAIL: dinkel@jpl.nasa.gov
|
||||
# DATE CREATED: December 15, 2015
|
||||
#
|
||||
# Copyright 2015, California Institute of Technology.
|
||||
# ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged.
|
||||
#===============================================================================
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import copy
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from fprime.gds.models.serialize.time_type import *
|
||||
|
||||
from fprime.gds.models.serialize.bool_type import *
|
||||
from fprime.gds.models.serialize.enum_type import *
|
||||
from fprime.gds.models.serialize.f32_type import *
|
||||
from fprime.gds.models.serialize.f64_type import *
|
||||
|
||||
from fprime.gds.models.serialize.u8_type import *
|
||||
from fprime.gds.models.serialize.u16_type import *
|
||||
from fprime.gds.models.serialize.u32_type import *
|
||||
from fprime.gds.models.serialize.u64_type import *
|
||||
|
||||
from fprime.gds.models.serialize.i8_type import *
|
||||
from fprime.gds.models.serialize.i16_type import *
|
||||
from fprime.gds.models.serialize.i32_type import *
|
||||
from fprime.gds.models.serialize.i64_type import *
|
||||
|
||||
from fprime.gds.models.serialize.string_type import *
|
||||
from fprime.gds.models.serialize.serializable_type import *
|
||||
|
||||
import zlib
|
||||
|
||||
Descriptor = Enum(value='Descriptor', names='ABSOLUTE RELATIVE')
|
||||
|
||||
__author__ = "Kevin Dinkel"
|
||||
__copyright__ = "Copyright 2015, California Institute of Technology."
|
||||
__version__ = "1.0"
|
||||
__email__ = "kevin.dinkel@jpl.nasa.gov"
|
||||
|
||||
class SeqBinaryWriter(object):
|
||||
"""
|
||||
Write out the Binary (ASTERIA) form of sequencer file.
|
||||
"""
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.__fd = None
|
||||
|
||||
|
||||
def open(self, filename):
|
||||
"""
|
||||
Open the ASCII file
|
||||
"""
|
||||
self.__fd = open(filename, "wb")
|
||||
|
||||
def __binaryCmdRecord(self, cmd_obj):
|
||||
"""
|
||||
Return the binary command record the sequencer is expecting.
|
||||
@todo: Currently the command descriptor is always zero for immediate commands.
|
||||
@todo: Execution time tags needed in command objects and seq_panel.
|
||||
"""
|
||||
|
||||
def __time_tag(cmd_obj):
|
||||
'''
|
||||
TODO: support a timebase in the cmd obj? This is mission specific, so it is tough to handle. For now
|
||||
I am hardcoding this to 2 which is TB_NONE
|
||||
'''
|
||||
#return TimeType(timeBase=2, seconds=cmd_obj.getSeconds(), useconds=cmd_obj.getUseconds()).serialize()
|
||||
# TKC - new command time format
|
||||
return U32Type( cmd_obj[1].time.seconds ).serialize() + U32Type( cmd_obj[1].time.useconds ).serialize()
|
||||
|
||||
def __descriptor(cmd_obj):
|
||||
# subtract 1 from the value because enum34 enums start at 1, and this can't be changed
|
||||
return U8Type(cmd_obj[0].value-1).serialize()
|
||||
|
||||
def __command(cmd_obj):
|
||||
command = U32Type( 0 ).serialize() # serialize combuffer type enum: FW_PACKET_COMMAND
|
||||
command += U32Type( cmd_obj[1].template.get_op_code() ).serialize() # serialize opcode
|
||||
# Command arguments
|
||||
for arg in cmd_obj[1].get_args():
|
||||
print(arg)
|
||||
command += arg.serialize()
|
||||
return command
|
||||
|
||||
def __length(command):
|
||||
return U32Type( len(command) ).serialize()
|
||||
|
||||
def __print(byteBuffer):
|
||||
print "Byte buffer size: %d" % len(byteBuffer)
|
||||
for entry in range(0,len(byteBuffer)):
|
||||
print "Byte %d: 0x%02X (%c)"%(entry,struct.unpack("B",byteBuffer[entry])[0],struct.unpack("B",byteBuffer[entry])[0])
|
||||
|
||||
# This is no longer in the sequence file format.
|
||||
#def __checksum(data):
|
||||
# csum = 0
|
||||
# for entry in range(0,len(data)):
|
||||
# byte = struct.unpack("B",data[entry])[0]
|
||||
# csum += byte
|
||||
# return U64Type(long(csum)).serialize()
|
||||
|
||||
# Form header:
|
||||
descriptor = __descriptor(cmd_obj)
|
||||
time = __time_tag(cmd_obj)
|
||||
header = descriptor + time
|
||||
|
||||
# Command opcode:
|
||||
command = __command(cmd_obj)
|
||||
|
||||
# Command length:
|
||||
length = __length(command)
|
||||
|
||||
# Checksum:
|
||||
# This is no longer in the sequence file format.
|
||||
#checksum = __checksum(header + length + command)
|
||||
|
||||
# Debug printing (comment out when not debugging):
|
||||
# print "descriptor:"
|
||||
# __print(descriptor)
|
||||
# print "time:"
|
||||
# __print(time)
|
||||
# print "length:"
|
||||
# __print(length)
|
||||
# print "command:"
|
||||
# __print(command)
|
||||
# print "total record:"
|
||||
# __print(header + checksum + length + command)
|
||||
|
||||
# Construct the record:
|
||||
return header + length + command
|
||||
|
||||
def write(self, seq_cmds_list):
|
||||
"""
|
||||
Write out each record as it appears in the listbox widget.
|
||||
"""
|
||||
num_records = len(seq_cmds_list)
|
||||
sequence = ""
|
||||
for cmd in seq_cmds_list:
|
||||
sequence += self.__binaryCmdRecord(cmd)
|
||||
size = len(sequence)
|
||||
print("Sequence is %d bytes"%size)
|
||||
|
||||
header = ""
|
||||
header += U32Type( size + 4 ).serialize() # Write out size of the sequence file in bytes here
|
||||
header += U32Type( num_records ).serialize() # Write number of records
|
||||
header += U16Type( 0xFFFF ).serialize() # Write time base FIXME: Set to don't care = 0xFFFF for now
|
||||
header += U8Type( 0xFF ).serialize() # write time context
|
||||
sequence = header + sequence # Write the list of command records here
|
||||
# compute CRC. Ported from Utils/Hassh/libcrc/libcrc.h (update_crc_32)
|
||||
crc = self.computeCrc(sequence)
|
||||
|
||||
print "CRC: %d (0x%04X)"%(crc,crc)
|
||||
try:
|
||||
sequence += U32Type( crc ).serialize()
|
||||
except TypeMismatchException as typeErr:
|
||||
print "Exception: %s" % typeErr.getMsg()
|
||||
raise
|
||||
|
||||
# Write the list of command records here
|
||||
self.__fd.write( sequence )
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close the Binary file
|
||||
"""
|
||||
self.__fd.close()
|
||||
|
||||
def computeCrc(self, buff):
|
||||
# See http://stackoverflow.com/questions/30092226/how-to-calculate-crc32-with-python-to-match-online-results
|
||||
# RE: signed to unsigned CRC
|
||||
return zlib.crc32(buff)% (1<<32)
|
||||
|
||||
class SeqAsciiWriter(object):
|
||||
"""
|
||||
Write out the ASCII record form of sequencer file.
|
||||
"""
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.__fd = None
|
||||
|
||||
|
||||
def open(self, filename):
|
||||
"""
|
||||
Open the ASCII file
|
||||
"""
|
||||
self.__fd = open(filename, "w")
|
||||
|
||||
|
||||
def __getCmdString(self, cmd_obj):
|
||||
"""
|
||||
For an command return it stringified.
|
||||
"""
|
||||
mnemonic = cmd_obj.getMnemonic()
|
||||
opcode = cmd_obj.getOpCode()
|
||||
args = cmd_obj.getArgs()
|
||||
#
|
||||
cmd = "%s (0x%x)" % (mnemonic,int(opcode))
|
||||
for arg in args:
|
||||
cmd += ", %s" % arg[2].val
|
||||
return cmd
|
||||
|
||||
|
||||
def write(self, seq_cmds_list):
|
||||
"""
|
||||
Write out each record as it appears in the listbox widget.
|
||||
"""
|
||||
for cmd in seq_cmds_list:
|
||||
self.__fd.write(self.__getCmdString(cmd) + "\n")
|
||||
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close the ASCII file
|
||||
"""
|
||||
self.__fd.close()
|
||||
|
||||
|
||||
|
||||
def __error(string):
|
||||
'''
|
||||
Print an error message and exit with error code 1
|
||||
@param string: the custom error string to print
|
||||
'''
|
||||
print string
|
||||
sys.exit(1)
|
||||
|
||||
from fprime.gds.loaders import cmd_py_loader
|
||||
from fprime.gds.data_types import cmd_data
|
||||
|
||||
# try:
|
||||
# from fprime.gds.models.common.command import Descriptor
|
||||
# TODO might want to reimplement but probably doesn't matter
|
||||
from fprime.gds.controllers import exceptions as gseExceptions
|
||||
|
||||
# except:
|
||||
# __error("The Gse source code was not found in your $PYTHONPATH variable. Please set PYTHONPATH to something like: $BUILD_ROOT/Gse/src:$BUILD_ROOT/Gse/generated/$DEPLOYMENT_NAME")
|
||||
|
||||
def __errorLine(lineNumber, string):
|
||||
'''
|
||||
Print an error message relating to a line number of the file input and exit with error code 1
|
||||
@param lineNumber: the current line number being parsed
|
||||
@param string: the custom error string to print
|
||||
'''
|
||||
__error("Error on line %d: %s" % (lineNumber + 1, string))
|
||||
|
||||
def __parse(seqfile):
|
||||
'''
|
||||
Generator that parses an input sequence file and returns a tuple
|
||||
for each valid line of the sequence file.
|
||||
@param seqfile: A sequence file name (usually a .seq extension)
|
||||
@return A list of tuples:
|
||||
(lineNumber, descriptor, seconds, useconds, mnemonic, arguments)
|
||||
'''
|
||||
|
||||
def subQuoted(f, string):
|
||||
'''
|
||||
Run a substitution function on only substrings within a string that are surrounded
|
||||
by single or double quotes
|
||||
@param f: a string substitution acting on matchobjs
|
||||
@param string: the string to perform the substitution on
|
||||
@return the substituted string
|
||||
'''
|
||||
s = re.sub(r'"[^"]*"', f, string)
|
||||
return re.sub(r"'[^']*'", f, s)
|
||||
|
||||
def removeTrailingComments(string):
|
||||
'''
|
||||
Remove any trailing comments (proceded by ';') in a string
|
||||
@param string: the string to perform comment removal on
|
||||
@return the string without trailing comments
|
||||
'''
|
||||
def replaceSemis(matchobj):
|
||||
return matchobj.group(0).replace(';', ' ')
|
||||
# ignore all semicolons in quotes:
|
||||
s = subQuoted(replaceSemis, string)
|
||||
s = subQuoted(replaceSemis, s)
|
||||
# get index of first semicolon, and return everything before it:
|
||||
if ';' in s:
|
||||
index = s.index(';')
|
||||
return string[:index]
|
||||
# return original string if no semicolon found:
|
||||
return string
|
||||
|
||||
def splitString(string):
|
||||
'''
|
||||
Split a string with ' ' or ',' as a delimiter. Ignore any delimiters
|
||||
found within quoted substrings.
|
||||
@param string: the string to perform the split on
|
||||
@return a list representing the split string
|
||||
'''
|
||||
def replaceSpacesAndCommas(matchobj):
|
||||
s = re.sub('\s', '_', matchobj.group(0))
|
||||
s = re.sub('\,', '_', s)
|
||||
return s
|
||||
# ignore all spaces in quotes:
|
||||
s = subQuoted(replaceSpacesAndCommas, string)
|
||||
# replace all commas with spaces, since either can be a delimiter:
|
||||
s = s.replace(',', ' ')
|
||||
# get the split indices of the modified string:
|
||||
indices = [(m.start(), m.end()) for m in re.finditer(r'\S+', s)]
|
||||
toReturn = []
|
||||
for start, end in indices:
|
||||
toReturn.append(string[start:end])
|
||||
return toReturn
|
||||
|
||||
def parseArgs(args):
|
||||
'''
|
||||
Turn .seq command argument list into their appropriate python types
|
||||
@param args: a list of parsed arguments
|
||||
@return a list of arguments as native python types
|
||||
'''
|
||||
def parseArg(arg):
|
||||
# See if argument is a string, if so remove the quotes and return it:
|
||||
if (arg[0] == '"' and arg[-1] == '"') or (arg[0] == "'" and arg[-1] == "'"):
|
||||
return arg[1:-1]
|
||||
# If the string contains a "." assume that it is a float:
|
||||
elif "." in arg:
|
||||
return float(arg)
|
||||
else:
|
||||
try:
|
||||
# See if it translates to an integer:
|
||||
return int(arg)
|
||||
except ValueError:
|
||||
try:
|
||||
# See if it translates to a float:
|
||||
return float(arg)
|
||||
except ValueError:
|
||||
# Otherwise it is an enum type:
|
||||
return str(arg)
|
||||
return map(parseArg, args)
|
||||
|
||||
def parseTime(lineNumber, time):
|
||||
'''
|
||||
Parse a time string and return the command descriptor, seconds, and useconds of the time string
|
||||
@param lineNumber: the current line number where the time string was parsed
|
||||
@param time: the time string to parse
|
||||
@return a tuple (descriptor, seconds, useconds)
|
||||
'''
|
||||
|
||||
def parseTimeStringOption(timeStr, timeFmts):
|
||||
'''
|
||||
Parse a time string by trying to use different time formats, until one succeeds
|
||||
@param timeStr: the time string
|
||||
@param timeFmts: the time format used to parse the string
|
||||
@return the datetime object containing the parsed string
|
||||
'''
|
||||
def parseTimeString(timeFmt):
|
||||
try:
|
||||
return datetime.strptime(timeStr, timeFmt)
|
||||
except:
|
||||
return None
|
||||
|
||||
for fmt in timeFmts:
|
||||
dt = parseTimeString(fmt)
|
||||
if dt:
|
||||
return dt
|
||||
raise BaseException
|
||||
|
||||
def parseRelative(timeStr):
|
||||
'''
|
||||
Parse a relative time string
|
||||
@param timeStr: the time string
|
||||
@return the datetime object containing the parsed string
|
||||
'''
|
||||
options = ["%H:%M:%S.%f", "%H:%M:%S"]
|
||||
return parseTimeStringOption(timeStr, options)
|
||||
|
||||
def parseAbsolute(timeStr):
|
||||
'''
|
||||
Parse an absolute time string
|
||||
@param timeStr: the time string
|
||||
@return the datetime object containing the parsed string
|
||||
'''
|
||||
options = ["%Y-%jT%H:%M:%S.%f","%Y-%jT%H:%M:%S"]
|
||||
return parseTimeStringOption(timeStr, options)
|
||||
|
||||
descriptor = None
|
||||
d = time[0]
|
||||
t = time[1:]
|
||||
if d == 'R':
|
||||
descriptor = Descriptor.RELATIVE
|
||||
dt = parseRelative(t)
|
||||
delta = timedelta(hours=dt.hour, minutes=dt.minute, seconds=dt.second, microseconds=dt.microsecond).total_seconds()
|
||||
elif d == 'A':
|
||||
descriptor = Descriptor.ABSOLUTE
|
||||
dt = parseAbsolute(t)
|
||||
# See if timezone was specified. If not, use UTC
|
||||
if dt.tzinfo != None:
|
||||
print "Using timezone %s" % dt.tzinfo.tzname()
|
||||
epoch = datetime.fromtimestamp(0, dt.tzinfo)
|
||||
else:
|
||||
print "Using UTC timezone"
|
||||
epoch = datetime.utcfromtimestamp(0)
|
||||
delta = (dt - epoch).total_seconds()
|
||||
else:
|
||||
__error(lineNumber, "Invalid time descriptor '" + d + "' found. Descriptor should either be 'A' for absolute times or 'R' for relative times")
|
||||
seconds = int(delta)
|
||||
useconds = int((delta - seconds) * 1000000)
|
||||
return descriptor, seconds, useconds
|
||||
|
||||
# Open the sequence file and parse each line:
|
||||
with open(seqfile, "r") as inputFile:
|
||||
for i, line in enumerate(inputFile):
|
||||
line = line.strip()
|
||||
# ignore blank lines and comments
|
||||
if line and line[0] != ';':
|
||||
line = removeTrailingComments(line)
|
||||
line = splitString(line)
|
||||
length = len(line)
|
||||
if length < 2:
|
||||
__errorLine(i, "Each line must contain a minimum of two fields, time and command mnemonic\n")
|
||||
else:
|
||||
try:
|
||||
descriptor, seconds, useconds = parseTime(i, line[0])
|
||||
except:
|
||||
__errorLine(i, "Encountered syntax error parsing timestamp")
|
||||
mnemonic = line[1]
|
||||
args = []
|
||||
if length > 2:
|
||||
args = line[2:]
|
||||
try:
|
||||
args = parseArgs(args)
|
||||
except:
|
||||
__errorLine(i, "Encountered sytax error parsing arguments")
|
||||
yield i, descriptor, seconds, useconds, mnemonic, args
|
||||
|
||||
def generateSequence(inputFile, outputFile=None):
|
||||
'''
|
||||
Write a binary sequence file from a text sequence file
|
||||
@param inputFile: A text input sequence file name (usually a .seq extension)
|
||||
@param outputFile: An output binary sequence file name (usually a .bin extension)
|
||||
'''
|
||||
# Check the user environment:
|
||||
try:
|
||||
generated_path = os.environ['GSE_GENERATED_PATH']
|
||||
generated_command_path = generated_path + "/commands"
|
||||
except:
|
||||
__error("Environment variable 'GSE_GENERATED_PATH' not set. It should be set to something like '$BUILD_ROOT/Gse/generated/$DEPLOYMENT' and also added to $PYTHONPATH.")
|
||||
command_loader = cmd_py_loader.CmdPyLoader()
|
||||
try:
|
||||
_, command_obj_dict = command_loader.construct_dicts(generated_command_path)
|
||||
except Exception:
|
||||
__error("Environment variable 'GSE_GENERATED_PATH' is set to '" + generated_path + "'. This is not a valid directory. Make sure this variable is set correctly, and the GSE python deployment autocode as been installed in this location.")
|
||||
|
||||
# Parse the input file:
|
||||
command_list = []
|
||||
for i, descriptor, seconds, useconds, mnemonic, args in __parse(inputFile):
|
||||
# Make sure that command is in the command dictionary:
|
||||
if mnemonic in command_obj_dict:
|
||||
command_obj = cmd_data.CmdData(tuple([str(a) for a in args]), command_obj_dict[mnemonic], TimeType(seconds=seconds, useconds=useconds))
|
||||
|
||||
# Append this command to the command list:
|
||||
command_list.append((descriptor, command_obj))
|
||||
else:
|
||||
__errorLine(i, "'" + mnemonic + "' does not match any command in the command dictionary.")
|
||||
|
||||
# Write to the output file:
|
||||
writer = SeqBinaryWriter()
|
||||
if not outputFile:
|
||||
outputFile = os.path.splitext(inputFile)[0] + ".bin"
|
||||
try:
|
||||
writer.open(outputFile)
|
||||
except:
|
||||
__error("Encountered problem opening output file '" + outputFile + "'.")
|
||||
writer.write(command_list)
|
||||
writer.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
'''
|
||||
The main program if run from the commandline. Note that this file can also be used
|
||||
as a module by calling the generateSequence() function
|
||||
'''
|
||||
if len(sys.argv) == 2 or len(sys.argv) == 3:
|
||||
generateSequence(*sys.argv[1:])
|
||||
else:
|
||||
print "Usage: tinyseqgen sequence_file_in.seq [binary_sequence_file_out.bin]"
|
||||
print
|
||||
print "Welcome to tinyseqgen - the Tiny F Prime Command Sequence Generator."
|
||||
print
|
||||
print "Description: tinyseqgen takes a simple input sequence format (.seq),"
|
||||
print "and outputs a binary command sequence loadable by the Svc/SequenceFileLoader."
|
||||
print
|
||||
print "Here, try out this example input sequence file (simple_sequence.seq):"
|
||||
print
|
||||
print ";--------------------------------------------------------------------"
|
||||
print "; Simple sequence file "
|
||||
print "; Note: that anything after a ';' is a comment"
|
||||
print ";--------------------------------------------------------------------"
|
||||
print
|
||||
print "; Commands in a sequence can either be timed absolutely or relative "
|
||||
print "; to the execution of the previous command. Here is an absolute NOOP"
|
||||
print "; command. Make sure to use UTC times, since tinyseqgen will calculate"
|
||||
print "; the seconds since the unix epoch from the given absolute time in UTC."
|
||||
print "A2015-075T22:32:40.123 CMD_NO_OP"
|
||||
print
|
||||
print "; Here is a relative NOOP command, which will be run 1 second after"
|
||||
print "; the execution of the previous command"
|
||||
print "R00:00:01 CMD_NO_OP; Send a no op command"
|
||||
print
|
||||
print "; This command will run immediately after the previously executed command"
|
||||
print "; has completed"
|
||||
print "R00:00:00 CMD_NO_OP"
|
||||
print
|
||||
print "; Let's try out some commands with arguments"
|
||||
print "R01:00:01.050 CMD_NO_OP_STRING \"Awesome string!\"; <- cool argument right?"
|
||||
print "R03:51:01.000 CMD_TEST_CMD_1 17, 3.2, 2; <- this command has 3 arguments"
|
||||
print "R00:05:00 ALOG_SET_EVENT_REPORT_FILTER INPUT_COMMAND, INPUT_DISABLED; <- this command uses enum arguments"
|
||||
print
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
84
Gds/tkGui/bin/TlmPacketEditor.py
Normal file
84
Gds/tkGui/bin/TlmPacketEditor.py
Normal file
@ -0,0 +1,84 @@
|
||||
import Tkinter
|
||||
import ttk
|
||||
import logging
|
||||
import Pmw
|
||||
import sys
|
||||
import os
|
||||
import csv
|
||||
import tkFileDialog
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
from fprime.gse.utils import ConfigManager
|
||||
from fprime.gse.controllers import channel_loader
|
||||
from fprime.gse.models.tpe_models import SessionModel
|
||||
from fprime.gse.controllers.tpe_controllers import SessionController
|
||||
from fprime.gse.controllers.exceptions import GseControllerUndefinedDirectoryException
|
||||
|
||||
# Setup logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
sh = logging.StreamHandler()
|
||||
#sh.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
|
||||
Logger.addHandler(sh)
|
||||
Logger.setLevel(logging.DEBUG)
|
||||
|
||||
|
||||
|
||||
def main(opts):
|
||||
|
||||
root = Tkinter.Tk()
|
||||
root.minsize(500, 600)
|
||||
root.title("F Prime Telemetry Packet Editor")
|
||||
|
||||
# Try to load channels.
|
||||
ch_path = os.path.join(opts.gen_path, "channels")
|
||||
ch_loader = channel_loader.ChannelLoader.getInstance()
|
||||
|
||||
# Exit if they are not found.
|
||||
try:
|
||||
ch_loader.create(ch_path)
|
||||
except GseControllerUndefinedDirectoryException, e:
|
||||
alert_dialog(root)
|
||||
return
|
||||
|
||||
session_model = SessionModel(ch_loader)
|
||||
session_controller = SessionController(opts, root, session_model)
|
||||
session_controller.create_session()
|
||||
|
||||
root.mainloop()
|
||||
|
||||
|
||||
def alert_dialog(parent):
|
||||
dialog = Pmw.MessageDialog(parent,
|
||||
title = 'Error',
|
||||
buttons=('Exit',),
|
||||
iconpos = 'w',
|
||||
icon_bitmap = 'error',
|
||||
message_text = 'Cannot find channel dictionaries. Specify generated dictionary path with -d.')
|
||||
dialog.iconname('Generated Dictionary Error')
|
||||
dialog.activate()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
argv = sys.argv[1:]
|
||||
|
||||
program_version_string = "1.0"
|
||||
program_longdesc = ""
|
||||
program_license = ""
|
||||
|
||||
config_manager = ConfigManager.ConfigManager.getInstance()
|
||||
generated_path = config_manager.get("filepaths", "generated_path")
|
||||
|
||||
|
||||
parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
|
||||
parser.add_option("-d", "--dictionary", dest="gen_path", action="store", type="string", \
|
||||
help="Set base path to generated command/telemetry definition files [default: %default]", \
|
||||
default=generated_path)
|
||||
|
||||
(opts, args) = parser.parse_args(argv)
|
||||
|
||||
# Add to path so we can import channels
|
||||
sys.path.append(opts.gen_path)
|
||||
|
||||
main(opts)
|
||||
645
Gds/tkGui/bin/cmd_telm_monitor.py
Normal file
645
Gds/tkGui/bin/cmd_telm_monitor.py
Normal file
@ -0,0 +1,645 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('TkAgg')
|
||||
|
||||
from numpy import arange, sin, pi
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
from Tkinter import *
|
||||
import sys
|
||||
import threading
|
||||
import Queue
|
||||
import os
|
||||
import math
|
||||
import Pmw
|
||||
import struct
|
||||
import math
|
||||
import time
|
||||
from fprime.gse.controllers import client_sock
|
||||
#import ModeMgrSm
|
||||
|
||||
|
||||
class Plotter:
|
||||
"""
|
||||
Class to accept telemetry from multi-partiiions and sends commands.
|
||||
It also launches thread to generate fake simulation data.
|
||||
"""
|
||||
def __init__(self, master, width=500, height=350):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.root = master
|
||||
# Title
|
||||
self.status = Label(master, text="Multi-Partition Telemetry & Commander", justify=LEFT)
|
||||
self.status.pack(side=TOP)
|
||||
# Entry fields to support commands
|
||||
self.control3 = Frame(master)
|
||||
self.control3.pack(side=BOTTOM, fill=X, padx=2)
|
||||
# Buttons to launch demos
|
||||
self.control2 = Frame(master)
|
||||
self.control2.pack(side=BOTTOM, fill=X, padx=2)
|
||||
# Buttons to launch demos
|
||||
self.control = Frame(master)
|
||||
self.control.pack(side=BOTTOM, fill=X, padx=2)
|
||||
|
||||
# Build temp plot here for testing
|
||||
|
||||
self.fig = Figure(figsize=(6,3), dpi=100)
|
||||
self.axis = self.fig.add_subplot(111)
|
||||
|
||||
t = arange(0.0,3.0,0.01)
|
||||
s = sin(2*pi*t)
|
||||
t=[]
|
||||
s=[]
|
||||
# Initialize plots
|
||||
self.axis.plot(t,s)
|
||||
|
||||
# Label title, axis and turn on grid
|
||||
self.label_plot()
|
||||
|
||||
# a tk.DrawingArea
|
||||
canvas = FigureCanvasTkAgg(self.fig, master=master)
|
||||
canvas.show()
|
||||
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
|
||||
#
|
||||
toolbar = NavigationToolbar2TkAgg( canvas, master )
|
||||
toolbar.update()
|
||||
canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)
|
||||
#
|
||||
self.display = Pmw.ScrolledText(self.root, hscrollmode='dynamic',
|
||||
vscrollmode='dynamic', hull_relief='sunken',
|
||||
hull_background='gray40', hull_borderwidth=10,
|
||||
text_background='white', text_width=16,
|
||||
text_foreground='black', text_height=10,
|
||||
text_padx=10, text_pady=10, text_relief='groove',
|
||||
text_font=('arial', 12, 'bold'))
|
||||
self.display.pack(side=TOP, expand=YES, fill=BOTH)
|
||||
self.display.tag_config('ans', foreground='red')
|
||||
self.display.tag_config('blue', foreground='blue')
|
||||
self.display.tag_config('red', foreground='red')
|
||||
self.display.tag_config('green', foreground='green')
|
||||
self.display.tag_config('black', foreground='black')
|
||||
# Quit
|
||||
self.quit_bt = Button(self.control, text='Quit', activebackground="pink", command=self.quit)
|
||||
self.quit_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# Connect
|
||||
self.connect_bt = Button(self.control, text='Connect', activebackground="pink", command=self.connect)
|
||||
self.connect_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# Clear
|
||||
self.clear_bt = Button(self.control, text='Clear', activebackground="pink", command=self.clear)
|
||||
self.clear_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# Play
|
||||
self.play_bt = Button(self.control, text='List', activebackground="pink", command=self.list)
|
||||
self.play_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# Pause
|
||||
self.pause_bt = Button(self.control, text='Play', activebackground="pink", command=self.play)
|
||||
self.pause_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# Stop
|
||||
self.stop_bt = Button(self.control, text='Stop', activebackground="pink", command=self.stop)
|
||||
self.stop_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# opcode 1
|
||||
self.op1_bt = Button(self.control2, text='Mode Change', activebackground="pink", command=self.op1)
|
||||
self.op1_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# opcode 2
|
||||
self.op2_bt = Button(self.control2, text='Set Param', activebackground="pink", command=self.op2)
|
||||
self.op2_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# opcode 3
|
||||
self.op3_bt = Button(self.control2, text='Get Param', activebackground="pink", command=self.op3)
|
||||
self.op3_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# opcode 4
|
||||
self.op4_bt = Button(self.control2, text='Test Cent. (x,y)', activebackground="pink", command=self.op4)
|
||||
self.op4_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
# opcode 5
|
||||
self.op5_bt = Button(self.control2, text='Test ARS Data', activebackground="pink", command=self.op5)
|
||||
self.op5_bt.pack(side=LEFT, fill=X, expand=True)
|
||||
#
|
||||
# Entry fields to support command.
|
||||
#
|
||||
self.mode_signal = 1
|
||||
self.signals = ["OnCmd", "OffCmd", "ARS_On", "ARS_Off", "Centroid_On", "Centroid_Off",
|
||||
"Show_SM_GUI", "Hide_SM_GUI"]
|
||||
self.mode_entry = Pmw.ComboBox(self.control3,
|
||||
scrolledlist_items=self.signals,
|
||||
selectioncommand = self.changeMode)
|
||||
self.mode_entry.pack(side=LEFT, fill=X, expand=False)
|
||||
self.mode_entry.selectitem(0, setentry = 1)
|
||||
self.mode_entry.component("entryfield").configure(validate=self.validateMode)
|
||||
#
|
||||
self.set_param = Pmw.EntryField(self.control3, value=1.0,
|
||||
validate='real')
|
||||
self.set_param.pack(side=LEFT, fill=X, expand=False)
|
||||
#
|
||||
self.get_param = Pmw.EntryField(self.control3, value="Params",
|
||||
validate='alphanumeric')
|
||||
self.get_param.pack(side=LEFT, fill=X, expand=False)
|
||||
#
|
||||
self.test_cent = Pmw.EntryField(self.control3, value='0 0',
|
||||
validate=self.cent_coord_validate)
|
||||
self.test_cent.pack(side=LEFT, fill=X, expand=False)
|
||||
self.cent_coord_validate_ok = True
|
||||
#
|
||||
self.test_ars = Pmw.EntryField(self.control3, value='0.0 0.0 0.0',
|
||||
validate=self.ars_validate)
|
||||
self.test_ars.pack(side=LEFT, fill=X, expand=False)
|
||||
self.ars_validate_ok = True
|
||||
#
|
||||
# Socket when connection established
|
||||
#
|
||||
self.sock = None
|
||||
# Store thread here
|
||||
self.thread = threading.Thread()
|
||||
self.thread2 = threading.Thread()
|
||||
# Instance a lock and make all socket read/write atomic
|
||||
self.lock = threading.Lock()
|
||||
# Create Queue for telemetry here
|
||||
self.queue = Queue.Queue()
|
||||
# Create Queue for simulation data here
|
||||
self.queue2 = Queue.Queue()
|
||||
# Define plot format for each instance here
|
||||
# Note that instance id is index to list
|
||||
# Note: Adding a "-" results in lines in replot only.
|
||||
self.plot_fmt = []
|
||||
self.plot_fmt.append("ro")
|
||||
self.plot_fmt.append("g^")
|
||||
self.plot_fmt.append("c<")
|
||||
self.plot_fmt.append("m>")
|
||||
#
|
||||
self.i = 0
|
||||
#
|
||||
width = 600
|
||||
height = 600
|
||||
x = 500
|
||||
y = 500
|
||||
# self.mode_mgr_sm_win = ModeMgrSm.ModeMgrSm("ModeMgrSm", big_name="Mode Manager State Machine", size=16)
|
||||
# self.mode_mgr_sm_win.win.geometry("%dx%d+%d+%d" % (width, height, x, y))
|
||||
# self.mode_mgr_sm_win.win.withdraw()
|
||||
|
||||
def cent_coord_validate(self, text):
|
||||
"""
|
||||
Check that entry is (x y) where x and y are integer.
|
||||
"""
|
||||
self.cent_coord_validate_ok = False
|
||||
if len(text.split(" ")) != 2:
|
||||
return Pmw.PARTIAL
|
||||
x,y = text.split(" ")
|
||||
if not x.isdigit():
|
||||
return Pmw.PARTIAL
|
||||
if not y.isdigit():
|
||||
return Pmw.PARTIAL
|
||||
self.cent_coord_validate_ok = True
|
||||
return Pmw.OK
|
||||
|
||||
def ars_validate(self, text):
|
||||
"""
|
||||
Check that entry is (x y z) where x, y, z are float.
|
||||
"""
|
||||
self.ars_validate_ok = False
|
||||
if len(text.split(" ")) != 3:
|
||||
return Pmw.PARTIAL
|
||||
x,y,z = text.split(" ")
|
||||
xp = x.partition(".")
|
||||
if not (xp[0].isdigit() and xp[1]=='.' and xp[2].isdigit()):
|
||||
return Pmw.PARTIAL
|
||||
yp = y.partition(".")
|
||||
if not (yp[0].isdigit() and yp[1]=='.' and yp[2].isdigit()):
|
||||
return Pmw.PARTIAL
|
||||
zp = z.partition(".")
|
||||
if not (zp[0].isdigit() and zp[1]=='.' and zp[2].isdigit()):
|
||||
return Pmw.PARTIAL
|
||||
self.ars_validate_ok = True
|
||||
return Pmw.OK
|
||||
|
||||
def set_demo_lim(self):
|
||||
"""
|
||||
Set axis limits for long trajectory demo.
|
||||
"""
|
||||
self.axis.set_xlim(0.0, 50.0)
|
||||
#self.axis.set_ylim(-1.25, 1.25)
|
||||
self.axis.set_ylim(-50.0, 50.0)
|
||||
|
||||
def set_auto_lim(self):
|
||||
"""
|
||||
Set autoscale of axis
|
||||
"""
|
||||
self.axis.relim()
|
||||
self.axis.autoscale_view(True,True,True)
|
||||
|
||||
|
||||
def label_plot(self):
|
||||
"""
|
||||
Refresh plot labels and settings
|
||||
"""
|
||||
self.axis.grid()
|
||||
|
||||
self.axis.set_title("Notional Tip/Tilt Position Update")
|
||||
self.axis.set_ylabel("Tip/Tilt (radians)")
|
||||
self.axis.set_xlabel("N (counts)")
|
||||
|
||||
# Set default xy axis
|
||||
self.set_demo_lim()
|
||||
|
||||
# Button row 1 functionality here...
|
||||
def list(self):
|
||||
self.root.update_idletasks()
|
||||
if self.sock != None:
|
||||
self.lock.acquire()
|
||||
self.sock.send("List\n")
|
||||
self.lock.release()
|
||||
else:
|
||||
self.status.config(text="SOCKET NOT CONNECTED TO SERVER...", fg="red")
|
||||
|
||||
def play(self):
|
||||
self.root.update_idletasks()
|
||||
if self.sock != None:
|
||||
self.queue2.put("PLAY")
|
||||
self.display.insert(END, "Sent PLAY request to sim thread...\n", "green")
|
||||
else:
|
||||
self.status.config(text="SOCKET NOT CONNECTED TO SERVER...", fg="red")
|
||||
|
||||
def stop(self):
|
||||
self.root.update_idletasks()
|
||||
if self.sock != None:
|
||||
self.queue2.put("STOP")
|
||||
self.display.insert(END, "Sent STOP request to sim thread...\n", "green")
|
||||
else:
|
||||
self.status.config(text="SOCKET NOT CONNECTED TO SERVER...", fg="red")
|
||||
|
||||
# Button row 2 functionality here...
|
||||
def app_cmd(self, msg):
|
||||
"""
|
||||
Package command for server to send to APP
|
||||
"""
|
||||
if self.sock != None:
|
||||
cmd = "A5A5 " + "APP " + msg
|
||||
self.lock.acquire()
|
||||
self.sock.send(cmd)
|
||||
self.lock.release()
|
||||
else:
|
||||
self.status.config(text="SOCKET NOT CONNECTED TO SERVER...", fg="red")
|
||||
|
||||
def app_cmd_fmt(self, op,s1,i1,i2,f1,f2):
|
||||
"""
|
||||
Packet format for basic command
|
||||
"""
|
||||
n = 0
|
||||
l = 80
|
||||
fmt = "Message sent: (%d,%s,%d,%d,%d,%f,%f,%d)\n"
|
||||
msg = struct.pack(">I80s3i",op,s1,l,i1,i2) + struct.pack("2f",f1,f2) + struct.pack(">i",n)
|
||||
print fmt % (op,s1,l,i1,i2,f1,f2,n)
|
||||
self.display.insert(END, fmt % (op,s1,l,i1,i2,f1,f2,n), "black")
|
||||
self.display.see(END)
|
||||
return msg
|
||||
|
||||
def op1(self):
|
||||
"""
|
||||
Execute op 1 command
|
||||
"""
|
||||
val = int(self.mode_signal)
|
||||
msg = self.app_cmd_fmt(1, "", val, 0, 0.0, 0.0)
|
||||
self.app_cmd(msg)
|
||||
|
||||
def changeMode(self, text):
|
||||
"""
|
||||
Set the mode manager mode, or hide/show mode mgr display
|
||||
"""
|
||||
item = self.mode_entry.getvalue()[0]
|
||||
if item == "Show_SM_GUI":
|
||||
self.mode_signal = 1
|
||||
self.mode_mgr_sm_win.win.deiconify()
|
||||
self.mode_mgr_sm_win.win.lift(self.root)
|
||||
elif item == "Hide_SM_GUI":
|
||||
self.mode_signal = 1
|
||||
self.mode_mgr_sm_win.win.withdraw()
|
||||
elif item.isdigit():
|
||||
self.mode_signal = int(item)
|
||||
else:
|
||||
self.mode_signal = self.signals.index(item) + 1
|
||||
# print self.mode_signal
|
||||
|
||||
def validateMode(self, text):
|
||||
"""
|
||||
Validate mode is in the list or a number of 1 to 6 here.
|
||||
"""
|
||||
if text in self.signals:
|
||||
return Pmw.OK
|
||||
if text.isdigit():
|
||||
if 0 < int(text) < 7:
|
||||
return Pmw.OK
|
||||
return Pmw.PARTIAL
|
||||
|
||||
def op2(self):
|
||||
val = float(self.set_param.getvalue())
|
||||
msg = self.app_cmd_fmt(2, "", 0, 0, val, 0.0)
|
||||
self.app_cmd(msg)
|
||||
|
||||
def op3(self):
|
||||
val = self.get_param.getvalue()
|
||||
msg = self.app_cmd_fmt(3, val, 0, 0, 0.0, 0.0)
|
||||
self.app_cmd(msg)
|
||||
|
||||
def op4(self):
|
||||
"""
|
||||
Send x, y and increment each time...
|
||||
"""
|
||||
if self.cent_coord_validate_ok:
|
||||
val = self.test_cent.getvalue().split(" ")
|
||||
n = 1
|
||||
x = int(val[0])
|
||||
y = int(val[1])
|
||||
msg = struct.pack(">3i",x,y,n)
|
||||
#
|
||||
# Make msg 108 bytes like command
|
||||
buf = 96*"A5"
|
||||
msg = struct.pack(">96s",buf) + msg
|
||||
self.app_cmd(msg)
|
||||
self.display.insert(END, "opcode=%d, Coord=(%d,%d)\n" % (n,x,y),"black")
|
||||
self.display.see(END)
|
||||
|
||||
|
||||
def op5(self):
|
||||
"""
|
||||
Send x, y, z and increment each fractionally...
|
||||
"""
|
||||
if self.ars_validate_ok:
|
||||
c = self.test_ars.getvalue().split(" ")
|
||||
n = 2
|
||||
f1 = float(c[0])
|
||||
f2 = float(c[1])
|
||||
f3 = float(c[2])
|
||||
msg = struct.pack("3f",f1,f2,f3) + struct.pack(">i",n)
|
||||
#
|
||||
# Make msg 108 bytes like command
|
||||
buf = 92*"A5"
|
||||
msg = struct.pack(">92s",buf) + msg
|
||||
self.app_cmd(msg)
|
||||
self.display.insert(END, "opcode=%d, Angles=(%f,%f,%f)\n" % (n,f1,f2,f3),"black")
|
||||
self.display.see(END)
|
||||
|
||||
|
||||
def quit(self):
|
||||
"""
|
||||
Quit the plotter
|
||||
"""
|
||||
self.clear()
|
||||
root.quit()
|
||||
root.destroy()
|
||||
|
||||
|
||||
def receive_telemetry(self, sock):
|
||||
"""
|
||||
Receive telemetry by first reading 4 byte size,
|
||||
then reading size bytes of serial telemetry
|
||||
and returning it as a message.
|
||||
"""
|
||||
msg = sock.recv(4)
|
||||
size = int(struct.unpack("i",msg)[0])
|
||||
data = sock.recv(size)
|
||||
return data
|
||||
|
||||
|
||||
def enqueue_output(self, sock, queue):
|
||||
"""
|
||||
Queue up socket telemetry for TK processing
|
||||
"""
|
||||
while 1:
|
||||
try:
|
||||
#x = sock.receive()
|
||||
x = self.receive_telemetry(sock)
|
||||
queue.put(x)
|
||||
except RuntimeError:
|
||||
queue.put("terminate")
|
||||
print "Socket connection terminated"
|
||||
break
|
||||
return
|
||||
|
||||
|
||||
def enqueue_sim_output(self, sock, queue):
|
||||
"""
|
||||
Queue up socket sim ARS data for C++ app commanding
|
||||
"""
|
||||
angle = 0.0
|
||||
while 1:
|
||||
try:
|
||||
msg = queue.get()
|
||||
if msg == "PLAY":
|
||||
while 1:
|
||||
# Update rate is 2 hz.
|
||||
time.sleep(0.5)
|
||||
# Compute x, y, z sin phased by 45 degree each
|
||||
P = 45.0 * (math.pi/180.0)
|
||||
# Phase
|
||||
G = 1.0
|
||||
# Angle sin values
|
||||
x = G * math.sin(angle)
|
||||
y = G * math.sin(angle + P)
|
||||
z = G * math.sin(angle + 2*P)
|
||||
# Angle increment value
|
||||
angle += 10.0 * (math.pi/180.0)
|
||||
#print time.time(), x, y, z
|
||||
n = 2
|
||||
msg = struct.pack("3f",x,y,z) + struct.pack(">i",n)
|
||||
#
|
||||
# Make msg 108 bytes like command
|
||||
buf = 92*"A5"
|
||||
msg = struct.pack(">92s",buf) + msg
|
||||
#
|
||||
self.app_cmd(msg)
|
||||
|
||||
if not queue.empty():
|
||||
msg = queue.get()
|
||||
print msg
|
||||
if msg == "STOP":
|
||||
angle = 0.0
|
||||
break
|
||||
elif msg == "STOP":
|
||||
pass
|
||||
elif msg == "RESET":
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
except RuntimeError:
|
||||
queue.put("terminate")
|
||||
print "Socket connection terminated"
|
||||
break
|
||||
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
Connect to TRN filter state telemetry socket
|
||||
and start listener thread.
|
||||
"""
|
||||
if self.thread.isAlive() == True:
|
||||
print "LISTENER THREAD IS ALIVE!"
|
||||
return
|
||||
# connect to server TRN
|
||||
try:
|
||||
port = 50007
|
||||
server = "127.0.0.1"
|
||||
str = "Connected to server (host addr %s, port %d)" % (server, port)
|
||||
self.sock=client_sock.ClientSocket(server,port)
|
||||
#
|
||||
# Register the GUI with the server
|
||||
self.lock.acquire()
|
||||
self.sock.send("Register GUI\n")
|
||||
self.lock.release()
|
||||
except IOError:
|
||||
str = "EXCEPTION: Could not connect to socket at host addr %s, port %s" % (server, port)
|
||||
# update status
|
||||
self.status.config(text=str, fg="red")
|
||||
self.connect_bt.config(text="Disconnected", fg="black")
|
||||
self.sock = None
|
||||
return
|
||||
|
||||
if self.thread.daemon == False:
|
||||
# create background listener thread
|
||||
self.thread = threading.Thread(target=self.enqueue_output, args=(self.sock, self.queue))
|
||||
# thread dies with the program
|
||||
self.thread.daemon = True
|
||||
# state listener thread here
|
||||
self.thread.start()
|
||||
|
||||
if self.thread2.daemon == False:
|
||||
# create background sim data generator thread
|
||||
self.thread2 = threading.Thread(target=self.enqueue_sim_output, args=(self.sock, self.queue2))
|
||||
# thread dies with the program
|
||||
self.thread2.daemon = True
|
||||
# start simulation thread here
|
||||
self.thread2.start()
|
||||
# update status
|
||||
self.status.config(text=str, fg="red")
|
||||
self.connect_bt.config(text="Connected", fg="red")
|
||||
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
Clear all plots
|
||||
"""
|
||||
#if self.thread.isAlive() == True:
|
||||
# self.status.config(text="LISTENER THREAD IS ALIVE!",fg="red")
|
||||
# return
|
||||
self.i = 0
|
||||
self.axis.cla()
|
||||
self.label_plot()
|
||||
self.fig.canvas.draw()
|
||||
self.status.config(text="Cleared plot areas.",fg="black")
|
||||
self.fig.canvas.draw()
|
||||
self.display.clear()
|
||||
|
||||
|
||||
def updatePlots(self, n, x, y):
|
||||
"""
|
||||
Update plot with new point
|
||||
"""
|
||||
fmt = self.plot_fmt[0]
|
||||
fmt2 = self.plot_fmt[1]
|
||||
if n % 50.0 == 0:
|
||||
self.axis.set_xlim(n, n+50.0)
|
||||
self.axis.plot(n,x,fmt)
|
||||
self.axis.plot(n,y,fmt2)
|
||||
#
|
||||
# Update figure here
|
||||
self.fig.canvas.draw()
|
||||
|
||||
|
||||
def decode_telm(self, bmsg):
|
||||
"""
|
||||
Decode APP telemetry here and return a tuple.
|
||||
"""
|
||||
if bmsg[:4] == "List":
|
||||
bmsg = bmsg.split(" ")
|
||||
print "---Server connected to %s" % bmsg[1]
|
||||
self.display.insert(END, "---Server connected to %s\n" % bmsg[1], "blue")
|
||||
return []
|
||||
l = len(bmsg)
|
||||
msg = struct.unpack(">" + "%d" % l + "s",bmsg)
|
||||
#print msg
|
||||
#tid = struct.unpack(">i",msg[0][-5:-1])[0]
|
||||
tid = struct.unpack(">i",msg[0][-4:])[0]
|
||||
if tid == 1:
|
||||
args = struct.unpack("3f",msg[0][:-4])
|
||||
print "--- (raw tlm ARSDATA) %f, %f, %f\n" % args
|
||||
self.display.insert(END, "--- (raw tlm ARSDATA) %f, %f, %f\n" % args, "ans")
|
||||
l = [tid, args[0],args[1],args[2]]
|
||||
elif tid == 2:
|
||||
args = struct.unpack("2f",msg[0][:-4])
|
||||
print "--- (raw tlm FSMDATA) %f, %f\n" % args
|
||||
self.display.insert(END, "--- (raw tlm FSMDATA) %f, %f\n" % args, "ans")
|
||||
l = [tid, args[0],args[1]]
|
||||
elif tid == 3:
|
||||
args = struct.unpack("f",msg[0][:-4])
|
||||
print "--- (raw tlm PARAMDATA) %f\n" % args[0]
|
||||
self.display.insert(END, "--- (raw tlm PARAMDATA) %f\n" % args, "ans")
|
||||
l = [tid, args[0]]
|
||||
elif tid == 4:
|
||||
m = msg[0][0:80]
|
||||
args = struct.unpack("80s",m)
|
||||
print "--- (State Data) %s\n" % args
|
||||
self.display.insert(END, "--- (State Data) %s\n\n" % args, "ans")
|
||||
self.display.insert(END, "\n")
|
||||
l = [tid, args]
|
||||
else:
|
||||
print "Unrecognized telemetry id = %d\n" % tid
|
||||
self.display.insert(END, "ERROR: Unrecognized telemetry id = %d\n" % tid, "ans")
|
||||
l = []
|
||||
self.display.see(END)
|
||||
#print "Id is %d, msg is %s, args is %s" % (tid,msg,args)
|
||||
return l
|
||||
|
||||
|
||||
def update_task(self):
|
||||
"""
|
||||
Update telemetry and plots from socket here...
|
||||
"""
|
||||
time_period = 20
|
||||
time_period_no_output = 200
|
||||
# read line without blocking
|
||||
try:
|
||||
msg = self.queue.get_nowait()
|
||||
#print msg
|
||||
msg = self.decode_telm(msg)
|
||||
if len(msg) > 0:
|
||||
if msg[0] == 2:
|
||||
n = self.i
|
||||
x = msg[1]
|
||||
y = msg[2]
|
||||
self.updatePlots(n, x, y)
|
||||
self.i += 1
|
||||
if msg[0] == 4:
|
||||
state = msg[1][0].split(":")
|
||||
e = state[1].split(" ")[-1].strip("\x00")
|
||||
s1 = state[0]
|
||||
s2 = state[1].strip(" "+e).replace(" ","")
|
||||
s2 = s2.strip("\x00")
|
||||
s2 = s2.strip("ENTRY")
|
||||
s2 = s2.strip("EXIT")
|
||||
|
||||
state = s2 + ":" + s1
|
||||
#
|
||||
if e == "EXIT":
|
||||
self.mode_mgr_sm_win.ExitState(state)
|
||||
|
||||
if e == "ENTRY":
|
||||
self.mode_mgr_sm_win.EnterState(state)
|
||||
|
||||
#
|
||||
except Queue.Empty:
|
||||
#print('no output yet')
|
||||
self.root.after(time_period_no_output, self.update_task)
|
||||
return
|
||||
# ... do something with line
|
||||
#
|
||||
self.mode_mgr_sm_win.win.update_idletasks()
|
||||
self.root.update_idletasks()
|
||||
self.root.after(time_period, self.update_task)
|
||||
return
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = Tk()
|
||||
root.option_add('*Font', 'Verdana 10')
|
||||
root.title('Multi-Partition Demo Commander and Telmetry Monitor')
|
||||
p = Plotter(root)
|
||||
root.after(200, p.update_task)
|
||||
root.mainloop()
|
||||
60
Gds/tkGui/bin/gse_api_cmds.py
Normal file
60
Gds/tkGui/bin/gse_api_cmds.py
Normal file
@ -0,0 +1,60 @@
|
||||
#!/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from fprime.gse.utils.gse_api import GseApi
|
||||
from optparse import OptionParser
|
||||
|
||||
__version__ = 0.1
|
||||
__date__ = '2015-08-01'
|
||||
__updated__ = '2015-08-01'
|
||||
|
||||
def main(argv=None):
|
||||
|
||||
if argv is None:
|
||||
argv =sys.argv[1:]
|
||||
try:
|
||||
program_name = os.path.basename(sys.argv[0])
|
||||
program_version = "v0.1"
|
||||
program_build_date = "%s" % __updated__
|
||||
program_longdesc = '''''' # optional - give further explanation about what the program does
|
||||
program_license = "Copyright 2015 user_name (California Institute of Technology) \
|
||||
ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged."
|
||||
|
||||
program_version_string = '%%prog %s (%s)' % (program_version, program_build_date)
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
|
||||
parser.add_option("-d", "--dictionary", dest="generated_path", action="store", type="string", \
|
||||
help="Set base path to generated command/telemetry definition files")
|
||||
parser.add_option("-a", "--addr", dest="addr", action="store", type="string", help="set threaded tcp socket server address [default: %default]", \
|
||||
default="127.0.0.1")
|
||||
parser.add_option("-c", "--connect", action="store_true", dest="connect", help="Launches the Threaded TCP Socket Server on startup and connect to it [default: %default]", \
|
||||
default=False)
|
||||
parser.add_option("-p", "--port", dest="port", action="store", type="int", help="Set threaded tcp socket server port [default: %default]", \
|
||||
default=50000)
|
||||
#TODO: add arg to provide list of ids to monitor
|
||||
(opts, args) = parser.parse_args(argv)
|
||||
|
||||
except Exception, e:
|
||||
indent = len(program_name) * " "
|
||||
sys.stderr.write(program_name + ": " + repr(e) + "\n")
|
||||
sys.stderr.write(indent + " for help use --help\n")
|
||||
return 2
|
||||
|
||||
api = GseApi(generated_path=opts.generated_path, port=opts.port)
|
||||
cmd_list = api.list()
|
||||
print "List of commands found:", cmd_list
|
||||
time.sleep(1)
|
||||
api.send("CMD_NO_OP")
|
||||
time.sleep(1)
|
||||
api.send("CMD_NO_OP_STRING", args=['Foo'])
|
||||
time.sleep(1)
|
||||
api.send_wait_evr("CMD_TEST_CMD_1", 'OpCodeCompleted',[1,2.0,3])
|
||||
time.sleep(1)
|
||||
api.send_wait_tlm("CMD_NO_OP", 'OpCodeCompleted', timeout = 10, args=None)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
59
Gds/tkGui/bin/gse_api_monitor.py
Normal file
59
Gds/tkGui/bin/gse_api_monitor.py
Normal file
@ -0,0 +1,59 @@
|
||||
#!/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
#from gse_api import GseApi
|
||||
from fprime.gse.utils.gse_api import GseApi
|
||||
from optparse import OptionParser
|
||||
|
||||
__version__ = 0.1
|
||||
__date__ = '2015-08-01'
|
||||
__updated__ = '2015-08-01'
|
||||
|
||||
def main(argv=None):
|
||||
|
||||
if argv is None:
|
||||
argv =sys.argv[1:]
|
||||
try:
|
||||
program_name = os.path.basename(sys.argv[0])
|
||||
program_version = "v0.1"
|
||||
program_build_date = "%s" % __updated__
|
||||
program_longdesc = '''''' # optional - give further explanation about what the program does
|
||||
program_license = "Copyright 2015 user_name (California Institute of Technology) \
|
||||
ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged."
|
||||
|
||||
program_version_string = '%%prog %s (%s)' % (program_version, program_build_date)
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
|
||||
parser.add_option("-d", "--dictionary", dest="generated_path", action="store", type="string", \
|
||||
help="Set base path to generated command/telemetry definition files")
|
||||
parser.add_option("-a", "--addr", dest="addr", action="store", type="string", help="set threaded tcp socket server address [default: %default]", \
|
||||
default="127.0.0.1")
|
||||
parser.add_option("-c", "--connect", action="store_true", dest="connect", help="Launches the Threaded TCP Socket Server on startup and connect to it [default: %default]", \
|
||||
default=False)
|
||||
parser.add_option("-p", "--port", dest="port", action="store", type="int", help="Set threaded tcp socket server port [default: %default]", \
|
||||
default=50000)
|
||||
parser.add_option("-m", "--monitor", dest="monitor", action="store", type="string", help="Set type of telemetry to monitior [default: %default]", \
|
||||
default='ch')
|
||||
#TODO: add arg to provide list of ids to monitor
|
||||
(opts, args) = parser.parse_args(argv)
|
||||
|
||||
|
||||
api = GseApi(generated_path=opts.generated_path, port=opts.port)
|
||||
if opts.monitor == 'evr':
|
||||
print 'Listening for event telemetry'
|
||||
api.monitor_evr()
|
||||
else:
|
||||
print 'Listening for channelized telemetry'
|
||||
api.monitor_tlm()
|
||||
|
||||
except Exception, e:
|
||||
indent = len(program_name) * " "
|
||||
sys.stderr.write(program_name + ": " + repr(e) + "\n")
|
||||
sys.stderr.write(indent + " for help use --help\n")
|
||||
return 2
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1,4 +1,4 @@
|
||||
#!/bin/csh
|
||||
#!/bin/sh
|
||||
# *******************************************************************************
|
||||
# * Copyright 2013, by the California Institute of Technology.
|
||||
# * ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||
@ -13,23 +13,13 @@
|
||||
# * information to foreign countries or providing access to foreign
|
||||
# * persons.
|
||||
# *
|
||||
|
||||
if !($?BUILD_ROOT) then
|
||||
set curdir = "${PWD}"
|
||||
setenv BUILD_ROOT `dirname $0`/../..
|
||||
cd $BUILD_ROOT
|
||||
setenv BUILD_ROOT ${PWD}
|
||||
cd ${curdir}
|
||||
endif
|
||||
|
||||
DIRNAME="`dirname $0`"
|
||||
# Set BUILD_ROOT if unset or "" set the BUILD_ROOT to be the above dir
|
||||
if [ -z ${BUILD_ROOT} ]
|
||||
then
|
||||
export BUILD_ROOT="`cd ${DIRNAME}/../../..; pwd`"
|
||||
fi
|
||||
echo "BUILD_ROOT is: ${BUILD_ROOT}"
|
||||
|
||||
# Borrow some variables from build
|
||||
|
||||
setenv PYTHON_BASE `make -s -f ${BUILD_ROOT}/mk/makefiles/build_vars.mk print_python_base`
|
||||
echo "PYTHON_BASE: ${PYTHON_BASE}"
|
||||
|
||||
setenv LD_LIBRARY_PATH ${PYTHON_BASE}/lib
|
||||
setenv PYTHONPATH ${BUILD_ROOT}/Gds/src
|
||||
setenv GSE_GENERATED_PATH ${BUILD_ROOT}/Gse/generated/Ref
|
||||
${PYTHON_BASE}/bin/python ${BUILD_ROOT}/Gds/bin/tinyseqgen.py $*
|
||||
export PYTHONPATH="${BUILD_ROOT}/Gds"
|
||||
python "${BUILD_ROOT}/Gds/tkGui/bin/seqgen.py" "$@"
|
||||
31
Gds/tkGui/bin/run_tlmeditor.sh
Executable file
31
Gds/tkGui/bin/run_tlmeditor.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
# *******************************************************************************
|
||||
# * Copyright 2013, by the California Institute of Technology.
|
||||
# * ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||
# * acknowledged. Any commercial use must be negotiated with the Office
|
||||
# * of Technology Transfer at the California Institute of Technology.
|
||||
# *
|
||||
# * This software may be subject to U.S. export control laws and
|
||||
# * regulations. By accepting this document, the user agrees to comply
|
||||
# * with all applicable U.S. export laws and regulations. User has the
|
||||
# * responsibility to obtain export licenses,
|
||||
# * or other export authority as may be required before exporting such
|
||||
# * information to foreign countries or providing access to foreign
|
||||
# * persons.
|
||||
# *
|
||||
DIRNAME="`dirname $0`"
|
||||
# Set BUILD_ROOT if unset or "" set the BUILD_ROOT to be the above dir
|
||||
if [ -z ${BUILD_ROOT} ]
|
||||
then
|
||||
export BUILD_ROOT="`cd ${DIRNAME}/../..; pwd`"
|
||||
fi
|
||||
echo "BUILD_ROOT is: ${BUILD_ROOT}"
|
||||
|
||||
# Get binary output path
|
||||
export NATIVE_BUILD="`make -f ${BUILD_ROOT}/mk/makefiles/build_vars.mk print_native_build`"
|
||||
echo "NATIVE_BUILD: ${NATIVE_BUILD}"
|
||||
export OUTPUT_DIR="`make -f ${BUILD_ROOT}/mk/makefiles/build_vars.mk BUILD=$NATIVE_BUILD print_output_dir`"
|
||||
|
||||
echo "OUTPUT_DIR: ${OUTPUT_DIR}"
|
||||
export PYTHONPATH="${BUILD_ROOT}/Gse/src"
|
||||
python "${BUILD_ROOT}/Gse/bin/TLMPacketEditor.py" "$@"
|
||||
320
Gds/tkGui/bin/seqgen.py
Executable file
320
Gds/tkGui/bin/seqgen.py
Executable file
@ -0,0 +1,320 @@
|
||||
#!/usr/bin/env python
|
||||
#===============================================================================
|
||||
# NAME: tinyseqgen
|
||||
#
|
||||
# DESCRIPTION: A tiny sequence generator for F Prime. This sequence compiler takes a
|
||||
# .seq file as input and produces a binary sequence file compatible with the
|
||||
# F Prime sequence file loader and sequence file runner.
|
||||
# AUTHOR: Kevin Dinkel
|
||||
# EMAIL: dinkel@jpl.nasa.gov
|
||||
# DATE CREATED: December 15, 2015
|
||||
#
|
||||
# Copyright 2015, California Institute of Technology.
|
||||
# ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged.
|
||||
#===============================================================================
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import copy
|
||||
from datetime import datetime, timedelta
|
||||
from optparse import OptionParser
|
||||
|
||||
from fprime.common.models.serialize.type_exceptions import *
|
||||
|
||||
__author__ = "Kevin Dinkel"
|
||||
__copyright__ = "Copyright 2015, California Institute of Technology."
|
||||
__version__ = "1.0"
|
||||
__email__ = "kevin.dinkel@jpl.nasa.gov"
|
||||
|
||||
def __error(string):
|
||||
'''
|
||||
Print an error message and exit with error code 1
|
||||
@param string: the custom error string to print
|
||||
'''
|
||||
print string
|
||||
sys.exit(1)
|
||||
|
||||
# try:
|
||||
from fprime.common.models.common.command import Descriptor
|
||||
from tkGui.views.seq_panel import SeqBinaryWriter
|
||||
from tkGui.gse.controllers import command_loader
|
||||
from tkGui.gse.controllers import exceptions as gseExceptions
|
||||
|
||||
# except:
|
||||
# __error("The Gse source code was not found in your $PYTHONPATH variable. Please set PYTHONPATH to something like: $BUILD_ROOT/Gse/src:$BUILD_ROOT/Gse/generated/$DEPLOYMENT_NAME")
|
||||
|
||||
def __errorLine(lineNumber, string):
|
||||
'''
|
||||
Print an error message relating to a line number of the file input and exit with error code 1
|
||||
@param lineNumber: the current line number being parsed
|
||||
@param string: the custom error string to print
|
||||
'''
|
||||
__error("Error on line %d: %s" % (lineNumber + 1, string))
|
||||
|
||||
def __parse(seqfile):
|
||||
'''
|
||||
Generator that parses an input sequence file and returns a tuple
|
||||
for each valid line of the sequence file.
|
||||
@param seqfile: A sequence file name (usually a .seq extension)
|
||||
@return A list of tuples:
|
||||
(lineNumber, descriptor, seconds, useconds, mnemonic, arguments)
|
||||
'''
|
||||
|
||||
def subQuoted(f, string):
|
||||
'''
|
||||
Run a substitution function on only substrings within a string that are surrounded
|
||||
by single or double quotes
|
||||
@param f: a string substitution acting on matchobjs
|
||||
@param string: the string to perform the substitution on
|
||||
@return the substituted string
|
||||
'''
|
||||
s = re.sub(r'"[^"]*"', f, string)
|
||||
return re.sub(r"'[^']*'", f, s)
|
||||
|
||||
def removeTrailingComments(string):
|
||||
'''
|
||||
Remove any trailing comments (proceded by ';') in a string
|
||||
@param string: the string to perform comment removal on
|
||||
@return the string without trailing comments
|
||||
'''
|
||||
def replaceSemis(matchobj):
|
||||
return matchobj.group(0).replace(';', ' ')
|
||||
# ignore all semicolons in quotes:
|
||||
s = subQuoted(replaceSemis, string)
|
||||
s = subQuoted(replaceSemis, s)
|
||||
# get index of first semicolon, and return everything before it:
|
||||
if ';' in s:
|
||||
index = s.index(';')
|
||||
return string[:index]
|
||||
# return original string if no semicolon found:
|
||||
return string
|
||||
|
||||
def splitString(string):
|
||||
'''
|
||||
Split a string with ' ' or ',' as a delimiter. Ignore any delimiters
|
||||
found within quoted substrings.
|
||||
@param string: the string to perform the split on
|
||||
@return a list representing the split string
|
||||
'''
|
||||
def replaceSpacesAndCommas(matchobj):
|
||||
s = re.sub('\s', '_', matchobj.group(0))
|
||||
s = re.sub('\,', '_', s)
|
||||
return s
|
||||
# ignore all spaces in quotes:
|
||||
s = subQuoted(replaceSpacesAndCommas, string)
|
||||
# replace all commas with spaces, since either can be a delimiter:
|
||||
s = s.replace(',', ' ')
|
||||
# get the split indices of the modified string:
|
||||
indices = [(m.start(), m.end()) for m in re.finditer(r'\S+', s)]
|
||||
toReturn = []
|
||||
for start, end in indices:
|
||||
toReturn.append(string[start:end])
|
||||
return toReturn
|
||||
|
||||
def parseArgs(args):
|
||||
'''
|
||||
Turn .seq command argument list into their appropriate python types
|
||||
@param args: a list of parsed arguments
|
||||
@return a list of arguments as native python types
|
||||
'''
|
||||
def parseArg(arg):
|
||||
# See if argument is a string, if so remove the quotes and return it:
|
||||
if (arg[0] == '"' and arg[-1] == '"') or (arg[0] == "'" and arg[-1] == "'"):
|
||||
return arg[1:-1]
|
||||
# If the string contains a "." assume that it is a float:
|
||||
elif "." in arg:
|
||||
return float(arg)
|
||||
elif arg == 'True' or arg == 'true' or arg == 'TRUE':
|
||||
return True
|
||||
elif arg == 'False' or arg == 'false' or arg == 'FALSE':
|
||||
return False
|
||||
else:
|
||||
try:
|
||||
# See if it translates to an integer:
|
||||
return int(arg,0)
|
||||
except ValueError:
|
||||
try:
|
||||
# See if it translates to a float:
|
||||
return float(arg)
|
||||
except ValueError:
|
||||
# Otherwise it is an enum type:
|
||||
return str(arg)
|
||||
return map(parseArg, args)
|
||||
|
||||
def parseTime(lineNumber, time):
|
||||
'''
|
||||
Parse a time string and return the command descriptor, seconds, and useconds of the time string
|
||||
@param lineNumber: the current line number where the time string was parsed
|
||||
@param time: the time string to parse
|
||||
@return a tuple (descriptor, seconds, useconds)
|
||||
'''
|
||||
|
||||
def parseTimeStringOption(timeStr, timeFmts):
|
||||
'''
|
||||
Parse a time string by trying to use different time formats, until one succeeds
|
||||
@param timeStr: the time string
|
||||
@param timeFmts: the time format used to parse the string
|
||||
@return the datetime object containing the parsed string
|
||||
'''
|
||||
def parseTimeString(timeFmt):
|
||||
try:
|
||||
return datetime.strptime(timeStr, timeFmt)
|
||||
except:
|
||||
return None
|
||||
|
||||
for fmt in timeFmts:
|
||||
dt = parseTimeString(fmt)
|
||||
if dt:
|
||||
return dt
|
||||
raise BaseException
|
||||
|
||||
def parseRelative(timeStr):
|
||||
'''
|
||||
Parse a relative time string
|
||||
@param timeStr: the time string
|
||||
@return the datetime object containing the parsed string
|
||||
'''
|
||||
options = ["%H:%M:%S.%f", "%H:%M:%S"]
|
||||
return parseTimeStringOption(timeStr, options)
|
||||
|
||||
def parseAbsolute(timeStr):
|
||||
'''
|
||||
Parse an absolute time string
|
||||
@param timeStr: the time string
|
||||
@return the datetime object containing the parsed string
|
||||
'''
|
||||
options = ["%Y-%jT%H:%M:%S.%f","%Y-%jT%H:%M:%S"]
|
||||
return parseTimeStringOption(timeStr, options)
|
||||
|
||||
descriptor = None
|
||||
d = time[0]
|
||||
t = time[1:]
|
||||
if d == 'R':
|
||||
descriptor = Descriptor.RELATIVE
|
||||
dt = parseRelative(t)
|
||||
delta = timedelta(hours=dt.hour, minutes=dt.minute, seconds=dt.second, microseconds=dt.microsecond).total_seconds()
|
||||
elif d == 'A':
|
||||
descriptor = Descriptor.ABSOLUTE
|
||||
dt = parseAbsolute(t)
|
||||
# See if timezone was specified. If not, use UTC
|
||||
if dt.tzinfo != None:
|
||||
print "Using timezone %s" % dt.tzinfo.tzname()
|
||||
epoch = datetime.fromtimestamp(0, dt.tzinfo)
|
||||
else:
|
||||
print "Using UTC timezone"
|
||||
epoch = datetime.utcfromtimestamp(0)
|
||||
delta = (dt - epoch).total_seconds()
|
||||
else:
|
||||
__error(lineNumber, "Invalid time descriptor '" + d + "' found. Descriptor should either be 'A' for absolute times or 'R' for relative times")
|
||||
seconds = int(delta)
|
||||
useconds = int((delta - seconds) * 1000000)
|
||||
return descriptor, seconds, useconds
|
||||
|
||||
# Open the sequence file and parse each line:
|
||||
with open(seqfile, "r") as inputFile:
|
||||
for i, line in enumerate(inputFile):
|
||||
line = line.strip()
|
||||
# ignore blank lines and comments
|
||||
if line and line[0] != ';':
|
||||
line = removeTrailingComments(line)
|
||||
line = splitString(line)
|
||||
length = len(line)
|
||||
if length < 2:
|
||||
__errorLine(i, "Each line must contain a minimum of two fields, time and command mnemonic\n")
|
||||
else:
|
||||
try:
|
||||
descriptor, seconds, useconds = parseTime(i, line[0])
|
||||
except:
|
||||
__errorLine(i, "Encountered syntax error parsing timestamp")
|
||||
mnemonic = line[1]
|
||||
args = []
|
||||
if length > 2:
|
||||
args = line[2:]
|
||||
try:
|
||||
args = parseArgs(args)
|
||||
except:
|
||||
__errorLine(i, "Encountered sytax error parsing arguments")
|
||||
yield i, descriptor, seconds, useconds, mnemonic, args
|
||||
|
||||
def generateSequence(inputFile, outputFile=None, generated_path, timebase):
|
||||
'''
|
||||
Write a binary sequence file from a text sequence file
|
||||
@param inputFile: A text input sequence file name (usually a .seq extension)
|
||||
@param outputFile: An output binary sequence file name (usually a .bin extension)
|
||||
'''
|
||||
# Check the user environment:
|
||||
generated_command_path = generated_path + "/commands"
|
||||
cmds = command_loader.CommandLoader.getInstance()
|
||||
try:
|
||||
cmds.create(generated_command_path)
|
||||
except gseExceptions.GseControllerUndefinedDirectoryException:
|
||||
__error("Environment variable 'GSE_GENERATED_PATH' is set to '" + generated_path + "'. This is not a valid directory. Make sure this variable is set correctly, and the GSE python deployment autocode as been installed in this location.")
|
||||
|
||||
# Parse the input file:
|
||||
command_list = []
|
||||
command_obj_dict = cmds.getCommandDict()
|
||||
for i, descriptor, seconds, useconds, mnemonic, args in __parse(inputFile):
|
||||
# Make sure that command is in the command dictionary:
|
||||
if mnemonic in command_obj_dict:
|
||||
command_obj = copy.deepcopy(command_obj_dict[mnemonic])
|
||||
# Set the command arguments:
|
||||
try:
|
||||
command_obj.setArgs(args)
|
||||
except ArgLengthMismatchException as e:
|
||||
__errorLine(i, "'" + mnemonic + "' argument length mismatch. " + e.getMsg())
|
||||
except TypeException as e:
|
||||
__errorLine(i, "'" + mnemonic + "' argument type mismatch. " + e.getMsg())
|
||||
# Set the command time and descriptor:
|
||||
command_obj.setDescriptor(descriptor)
|
||||
command_obj.setSeconds(seconds)
|
||||
command_obj.setUseconds(useconds)
|
||||
# Append this command to the command list:
|
||||
command_list.append(command_obj)
|
||||
else:
|
||||
__errorLine(i, "'" + mnemonic + "' does not match any command in the command dictionary.")
|
||||
|
||||
# Write to the output file:
|
||||
writer = SeqBinaryWriter(timebase=timebase)
|
||||
if not outputFile:
|
||||
outputFile = os.path.splitext(inputFile)[0] + ".bin"
|
||||
try:
|
||||
writer.open(outputFile)
|
||||
except:
|
||||
__error("Encountered problem opening output file '" + outputFile + "'.")
|
||||
writer.write(command_list)
|
||||
writer.close()
|
||||
|
||||
|
||||
help_text = "seqgen.py -d"
|
||||
|
||||
if __name__ == "__main__":
|
||||
'''
|
||||
The main program if run from the command line. Note that this file can also be used
|
||||
as a module by calling the generateSequence() function
|
||||
'''
|
||||
|
||||
usage = "usage: %prog [options] input_file output_file"
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-g", "--generated_path", dest="generated_path", action="store", type="string", \
|
||||
help="Set base path to generated command/telemetry definition files")
|
||||
parser.add_option("-t", "--timebase", dest="timebase", action="store", type="string", default = None, \
|
||||
help="Set base path to generated command/telemetry definition files [default: any]")
|
||||
|
||||
(opts, args) = parser.parse_args()
|
||||
|
||||
if opts.timebase == None:
|
||||
timebase = 0xffff
|
||||
else:
|
||||
try:
|
||||
timebase = int(opts.timebase,0)
|
||||
except ValueError:
|
||||
print("Could not parse time base %s"%opts.timebase)
|
||||
sys.exit(-1)
|
||||
|
||||
if (len(args) == 1 or len(args) == 2) and good:
|
||||
generateSequence(*args, generated_path=opts.generated_path,timebase=timebase)
|
||||
else:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
@ -35,5 +35,5 @@ setenv OUTPUT_DIR `make -f ${BUILD_ROOT}/mk/makefiles/build_vars.mk BUILD=$NATIV
|
||||
echo "OUTPUT_DIR: ${OUTPUT_DIR}"
|
||||
|
||||
setenv LD_LIBRARY_PATH ${PYTHON_BASE}/lib
|
||||
setenv PYTHONPATH ${BUILD_ROOT}/Gds/src
|
||||
setenv PYTHONPATH ${BUILD_ROOT}/Gds
|
||||
${PYTHON_BASE}/bin/python ${BUILD_ROOT}/Gds/bin/run_cmds.py $*
|
||||
@ -1,9 +0,0 @@
|
||||
import time
|
||||
|
||||
cycle = 0
|
||||
|
||||
while True:
|
||||
|
||||
time.sleep(0.5)
|
||||
print ("Cycle: %d"%cycle)
|
||||
cycle = cycle + 1
|
||||
@ -15,7 +15,7 @@ def main(argv=None):
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option("-p", "--port", dest="port", action="store", type="int", help="Set the threaded TCP socket server port [default: %default]", default=50000)
|
||||
parser.add_option("-a", "--addr", dest="addr", action="store", type="string", help="set the threaded TCP socket server address [default: %default]", default="localhost")
|
||||
parser.add_option("-a", "--addr", dest="addr", action="store", type="string", help="set the threaded TCP socket server address [default: %default]", default="0.0.0.0")
|
||||
parser.add_option("-n", "--nobin", dest="nobin", action="store_true", help="Disables the binary app from starting [default: %default]", default=False)
|
||||
parser.add_option("-t", "--twin", dest="twin", action="store_true", help="Runs Threaed TCP Server in window, otherwise backgrounds [default: %default]", default=False)
|
||||
|
||||
@ -30,18 +30,18 @@ def main(argv=None):
|
||||
|
||||
# run ThreadedTCPServer
|
||||
if twin:
|
||||
TTS_args = [python_bin,"%s/Gse/bin/pexpect_runner.py"%build_root,"ThreadedTCP.log","Threaded TCP Server",python_bin,"%s/Gse/bin/ThreadedTCPServer.py"%build_root,"--port","%d"%used_port, "--host",addr]
|
||||
TTS_args = [python_bin,"%s/Gds/tkGui/bin/pexpect_runner.py"%build_root,"ThreadedTCP.log","Threaded TCP Server",python_bin,"%s/Gse/bin/ThreadedTCPServer.py"%build_root,"--port","%d"%used_port, "--host",addr]
|
||||
TTS = subprocess.Popen(TTS_args)
|
||||
else:
|
||||
tts_log = open("ThreadedTCP.log",'w')
|
||||
TTS_args = [python_bin, "-u", "%s/Gse/bin/ThreadedTCPServer.py"%build_root,"--port","%d"%used_port, "--host",addr]
|
||||
TTS_args = [python_bin, "-u", "%s/Gds/bin/ThreadedTCPServer.py"%build_root,"--port","%d"%used_port, "--host",addr]
|
||||
TTS = subprocess.Popen(TTS_args,stdout=tts_log,stderr=subprocess.STDOUT)
|
||||
|
||||
# wait for TCP Server to start
|
||||
time.sleep(2)
|
||||
|
||||
# run Gse GUI
|
||||
GUI_args = [python_bin,"%s/Gse/bin/gse.py"%build_root,"--port","%d"%used_port,"--dictionary","%s/Gse/generated/Ref"%build_root,"--connect","--addr",addr,"-L","%s/Ref/logs"%build_root]
|
||||
GUI_args = [python_bin,"%s/Gds/tkGui/bin/gse.py"%build_root,"--port","%d"%used_port,"--dictionary","%s/Ref/py_dict"%build_root,"--connect","--addr",addr,"-L","%s/Ref/logs"%build_root]
|
||||
#print ("GUI: %s"%" ".join(GUI_args))
|
||||
GUI = subprocess.Popen(GUI_args)
|
||||
|
||||
@ -52,7 +52,7 @@ def main(argv=None):
|
||||
ref_bin = "%s/Ref/%s/Ref"%(build_root,os.environ["OUTPUT_DIR"])
|
||||
|
||||
if not nobin:
|
||||
REF_args = [python_bin,"%s/Gse/bin/pexpect_runner.py"%build_root,"Ref.log","Ref Application",ref_bin,"-p","%d"%used_port,"-a",addr]
|
||||
REF_args = [python_bin,"%s/Gds/tkGui/bin/pexpect_runner.py"%build_root,"Ref.log","Ref Application",ref_bin,"-p","%d"%used_port,"-a",addr]
|
||||
REF = subprocess.Popen(REF_args)
|
||||
|
||||
GUI.wait()
|
||||
|
||||
@ -25,6 +25,7 @@ export NATIVE_BUILD="`make -f ${BUILD_ROOT}/mk/makefiles/build_vars.mk print_nat
|
||||
echo "NATIVE_BUILD: ${NATIVE_BUILD}"
|
||||
export OUTPUT_DIR="`make -f ${BUILD_ROOT}/mk/makefiles/build_vars.mk BUILD=$NATIVE_BUILD print_output_dir`"
|
||||
echo "OUTPUT_DIR: ${OUTPUT_DIR}"
|
||||
export PYTHONPATH="${BUILD_ROOT}/Gds"
|
||||
echo "PYTHONPATH: ${PYTHONPATH}"
|
||||
|
||||
export PYTHONPATH="${BUILD_ROOT}/Gse/src"
|
||||
python ${BUILD_ROOT}/Ref/scripts/run_ref.py "$@" &
|
||||
|
||||
@ -16,15 +16,15 @@
|
||||
|Event Name|ID|Description|Arg Name|Arg Type|Arg Size|Description
|
||||
|---|---|---|---|---|---|---|
|
||||
|UR_PortOpened|0 (0x0)|Connection opened| | | | |
|
||||
| | | |port|U32|||
|
||||
| | | |port|U32|||
|
||||
|UR_SocketError|1 (0x1)|UDP port socket error| | | | |
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
|UR_BindError|2 (0x2)|UDP port socket error| | | | |
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
|UR_RecvError|3 (0x3)|UDP receive error| | | | |
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
|UR_DecodeError|4 (0x4)|Port decode error| | | | |
|
||||
| | | |stage|DecodeStage|||
|
||||
| | | |error|I32|||
|
||||
| | | |stage|DecodeStage|||
|
||||
| | | |error|I32|||
|
||||
|UR_DroppedPacket|5 (0x5)|Dropped packet was detected| | | | |
|
||||
| | | |diff|U32|||
|
||||
| | | |diff|U32|||
|
||||
|
||||
@ -14,9 +14,9 @@
|
||||
|Event Name|ID|Description|Arg Name|Arg Type|Arg Size|Description
|
||||
|---|---|---|---|---|---|---|
|
||||
|US_PortOpened|0 (0x0)|Connection opened| | | | |
|
||||
| | | |server|Fw::LogStringArg&|80||
|
||||
| | | |port|U32|||
|
||||
| | | |server|Fw::LogStringArg&|80||
|
||||
| | | |port|U32|||
|
||||
|US_SocketError|1 (0x1)|UDP port socket error| | | | |
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
|US_SendError|2 (0x2)|UDP send error| | | | |
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
| | | |error|Fw::LogStringArg&|80||
|
||||
|
||||
@ -210,5 +210,3 @@ OTHER_MODULES := \
|
||||
|
||||
DEPLOYMENTS := Ref acdev RPI
|
||||
|
||||
# Location of ground/gse software. Autocoded dictionary elements are copied here.
|
||||
GDS_MODULE := Gse
|
||||
|
||||
@ -103,54 +103,15 @@ comp_report_gen:
|
||||
@$(CAT) ComponentReport.txt
|
||||
|
||||
dict_clean:
|
||||
ifeq ($(DICT_GEN),"GLOBAL")
|
||||
@echo "Cleaning dictionary in $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable"
|
||||
@$(RM_DIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable
|
||||
else
|
||||
@echo "Cleaning dictionary in $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)"
|
||||
@$(RM_DIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)
|
||||
endif
|
||||
@echo "Cleaning dictionary in $(BUILD_ROOT)/$(DEPLOYMENT)/py_dict/serializable"
|
||||
@$(RM_DIR) $(BUILD_ROOT)/$(DEPLOYMENT)/py_dict/serializable
|
||||
|
||||
dict_install:
|
||||
ifeq ($(DICT_GEN),"GLOBAL")
|
||||
@echo "Installing instance dictionaries into $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)"
|
||||
@$(MKDIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable
|
||||
@#@$(MKDIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/events
|
||||
@#@$(MKDIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/channels
|
||||
@#@$(MKDIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/commands
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable/__init__.py
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/events/__init__.py
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/channels/__init__.py
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/commands/__init__.py
|
||||
@#@$(CP) $(wildcard $(BUILD_ROOT)/Autocoders/Python/bin/'default_dict/channels/*.py) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/channels
|
||||
@#@$(CP) $(wildcard $(BUILD_ROOT)/Autocoders/Python/bin/default_dict/events/*.py) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/events
|
||||
@#@$(CP) $(wildcard $(BUILD_ROOT)/Autocoders/Python/bin/default_dict/commands/*.py) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/commands
|
||||
@#@$(CP_RECURSE) $(wildcard $(BUILD_ROOT)/Autocoders/Python/bin/default_dict/serializable) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)
|
||||
@echo "Installing serializables in $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable"
|
||||
@$(MKDIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable/__init__.py
|
||||
@$(CP_RECURSE) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable/__init__.py $(foreach module,$($(DEPLOYMENT)_MODULES),$(wildcard $(BUILD_ROOT)/$(module)/$(DICT_MODULE_SUBDIR)/serializable)) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)
|
||||
else
|
||||
@echo "Installing dictionaries into $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)"
|
||||
@echo "Installing commands in $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/commands"
|
||||
@$(MKDIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/commands
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/__init__.py
|
||||
@$(CP) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/__init__.py $(foreach module,$($(DEPLOYMENT)_MODULES),$(wildcard $(BUILD_ROOT)/$(module)/$(DICT_MODULE_SUBDIR)/commands/*.py)) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/commands
|
||||
@echo "Installing telemetry in $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/channels"
|
||||
@$(MKDIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/channels
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/__init__.py
|
||||
@$(CP) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/__init__.py $(foreach module,$($(DEPLOYMENT)_MODULES),$(wildcard $(BUILD_ROOT)/$(module)/$(DEFAULT_DICT_MODULE_SUBDIR)/channels/*.py)) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/channels
|
||||
@echo "Installing events in $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/events"
|
||||
@$(MKDIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/events
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/__init__.py
|
||||
@$(CP) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/__init__.py $(foreach module,$($(DEPLOYMENT)_MODULES),$(wildcard $(BUILD_ROOT)/$(module)/$(DEFAULT_DICT_MODULE_SUBDIR)/events/*.py)) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/events
|
||||
@echo "Installing serializables in $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable"
|
||||
@$(MKDIR) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable/__init__.py
|
||||
@$(CP_RECURSE) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)/serializable/__init__.py $(foreach module,$($(DEPLOYMENT)_MODULES),$(wildcard $(BUILD_ROOT)/$(module)/$(DEFAULT_DICT_MODULE_SUBDIR)/serializable)) $(BUILD_ROOT)/$(GDS_MODULE)/generated/$(DEPLOYMENT)
|
||||
endif
|
||||
|
||||
|
||||
@echo "Installing instance dictionaries into $(BUILD_ROOT)/$(DEPLOYMENT)/py_dict"
|
||||
@$(MKDIR) $(BUILD_ROOT)/$(DEPLOYMENT)/py_dict/serializable
|
||||
@$(TOUCH) $(BUILD_ROOT)/$(DEPLOYMENT)/py_dict/serializable/__init__.py
|
||||
@echo "Installing serializables in $(BUILD_ROOT)/$(DEPLOYMENT)/py_dict/serializable"
|
||||
@$(CP_RECURSE) $(BUILD_ROOT)/$(DEPLOYMENT)/py_dict/serializable/__init__.py $(foreach module,$($(DEPLOYMENT)_MODULES),$(wildcard $(BUILD_ROOT)/$(module)/$(DICT_MODULE_SUBDIR)/serializable)) $(BUILD_ROOT)/$(DEPLOYMENT)/py_dict
|
||||
|
||||
gen_mod_sdds: $(foreach module,$($(DEPLOYMENT)_MODULES),$(subst /,,$(module))_sdd)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user