org-arl / unet-contrib

Unet user contributions
BSD 3-Clause "New" or "Revised" License
11 stars 15 forks source link

JANUS: frequency hopping pattern is incorrect #64

Closed tuff-krister closed 2 years ago

tuff-krister commented 2 years ago

Hello to the UnetStack team! This is Emil, a PhD student at NTNU. I am working with UnetStack-based modems and experimenting with manufacturer interoperability via JANUS. I believe I have discovered a bug in your implementation of JANUS, which is linked to the frequency hopping pattern.

What I observed

I produced a JANUS packet with the JANUS C 3.0.5 implementation and transmitted it using another manufacturer's modem, which supports JANUS. The Subnero RE modem that received it, which ran UnetStack 3.2.0, could detect this packet, but produced bad frame notifications with seemingly random contents. I sent a JANUS packet with identical bits from the Subnero modem, with similar results on the other end (packet detected, random contents).

When I investigated the transmitted signals by plotting their spectrograms, I noticed that the frequency hopping patterns were different. It appeared that the hopping pattern from UnetStack was offset with respect to the C implementation. When I looked closer immediately after the preamble, I noticed that the UnetStack hopping pattern had reset. This pattern offset was also observed when I loopback-recorded a JANUS packet with Unet Audio 3.3.0 and viewed its spectrogram.

How to reproduce

Spectrogram of UnetStack JANUS packet

Refer to this answer. Zoom in to the first 0.4 seconds in the spectrogram. The first 0.2 seconds should be very similar to the next 0.2 seconds. In fact, this can be seen in the spectrogram in the linked answer.

Spectrogram of reference JANUS packet

Find the transmission script that is produced after compiling the JANUS C implementation and execute it as follows.
./janus-tx --pset-file etc/parameter_sets.csv --pset-id 1
Launch a Python environment from the same folder, then run the following piece of code.

import scipy.io.wavfile as wav
import scipy.signal as dsp
import matplotlib.pyplot as plt
import numpy as np

fs, x = wav.read('./janus.wav')
fr, ts, spec = dsp.spectrogram(x, fs=fs, nperseg=256, nfft=512)
plt.pcolormesh(ts, fr, spec, shading='nearest')
plt.show() # can be skipped if using Jupyter notebook

Zoom in to the first 0.5 seconds in the spectrogram. The first half should not be similar to the next half.

Suggested solution

If the Unet JANUS implementation does generate a fresh hopping pattern after the preamble, discard the first 32 hops and compensate by extending the pattern length by an equal amount.

manuignatius commented 2 years ago

Thank you @tuff-krister for the detailed write-up. The issue has been fixed and will be available as part of the next release (v3.4) which should be out shortly.