I am currently getting into Kaitai to implement a parser for our PEGASUS satellite in SatNOGS. I am failing on implementing some user defined decoding methods. PEGASUS e.g. uses the Q-format to pack its data. Additional information can be found in the Ham Operator Manual page 7.
E.g. the following HEX-number is stored in UFix 3.5 and shall be decoded as followed: 0x7F → 0b01111111 → 0*(2^2) + 1*(2^1) + 1*(2^0) + 1*(2^-1) + 1*(2^-2) + 1*(2^-3) + 1*(2^-4) + 1*(2^-5) = 3.96875 (readable telemtry data for V_PV1)
Any ideas on how to implement this into Kaitai? I have two ideas:
Extract a raw-frame in seq, e.g.:
- id: v_pv1_raw
and then perform the decoding in an instance using value:, e.g.:
Use an external code to perform the decoding, e.g. for decoding 1 byte in HEX-format, I have a MWE for a Python-function, which uses a string with the binary data as input:
s = int(Bits)*(2**2) + int(Bits)*(2**1) + int(Bits)*(2**0) + int(Bits)*(2**-1) + int(Bits)*(2**-2) + int(Bits)*(2**-3) + int(Bits)*(2**-4) + int(Bits)*(2**-5)
data = '01111111' # 0x7f
x = Ufix35(data)
Nevertheless, I am failing on implementing on both ideas. For idea one, I do not know how to get from 0x7F to 0b01111111 in Kaitai, in order to implement the decoding routine using value:. Idea two is titled with “advanced” within the Kaitai user guide. Moreover, there exist several ways to implement it.
I would appreciate any help for implementing this decoding routine, since I am very unexperienced within this field.
For testing I am using data from a SatNOGS observation, which includes a 64 byte O1-Beacon (OBC data) of PEGASUS. Byte 0 is a HEX number and stores the PID (beacon identifier), Byte 1-6 is the CALLSIGN and Byte 7 stores the value for V_PV1 in Ufix3.5 format. For testing the data as well as my Kaitai-file can be downloaded here: pegasus.zip (444 Bytes).
If needed, detailed information for decoding can be found in the Ham Operator Manual mentioned above.
Many thanks for the fast reply! Concerning the MR I have contacted you via DM. I need to know:
Which branch (master, 1.60.0) should I use for devlopement? Currently, I have forked the 1.60.0 branch and added my files to it.
Based on that forked branch (source branch), which “target branch” should I select for the MR?
In the meantime I was able to solve my issue. I was able to implement a switch for the different beacon types. Moreover, I found a way on how to implement the Q-format using bit-sized integers and value instances, e.g.:
From 1 unsigned integer byte (v_pv1_raw), I extract the relevant bit using logical operations (e.g. & 0b10000000 to extract bit 7). After that I divide it by its actual value (e.g. 2^7 = 128) and multiply it by its value according to the Q-format, in this case 2^2=4 for bit 7 in the UFix3.5 format.
Maybe there exists a smarter solution. I also tried using bit-shifts, but I have always ended up with an integer, which is not sufficient for telemetry data needed as a float number.
master is the latest branch, while 1.60 is the latest tag that is deployed. In other words the tag is a screenshot of master at a certain commit which is deployed. So, you should develop in master, however as currently master and 1.60 tag are on the same commit it will not matter.
The target branch of the commit will be the master one.
I have some questions concerning the doc: section of the parser. What fields do I specifiy here? Are that the fields / parameters which will be parsed and pushed to SatNOGS DB in order to visualize them using a SatNOGS Dashboard?
I have following MWE. Do I specify the fields correct?
In that case, perhaps worth changing the order and putting the small (resulting in a float) calculation first, then adding the rest ?
Example on loosely defined style:
1 + 2 + 0.1 = 3 (first addition resulting in a inteter)
0.1 + 1 + 2 = 3.1 (first addition results in a float)
Another way is to define the variable in mV, that will then suffice with integers.
Concerning your suggestion of using mV:
Our official database uses V in float, therefore I would like to stick to it, since I already found a way to calculate it in that way in Kaitai (even if it is very ugly from a programmers view )