Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JY1-Sat isn't being decoded #196

Closed
janvgils opened this issue Nov 17, 2020 · 10 comments
Closed

JY1-Sat isn't being decoded #196

janvgils opened this issue Nov 17, 2020 · 10 comments
Assignees
Labels
recordings Problems processing recordings

Comments

@janvgils
Copy link
Contributor

janvgils commented Nov 17, 2020

Today we tried to decode a JY1-Sat SatNOGS observation but where not successful.

Below some information on versions and commands used.

user@hostname:~$ gr_satellites --version
gr_satellites v3.6.0-git
Copyright (C) 2020 Daniel Estevez
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

We used the following observation:

https://network.satnogs.org/observations/3154621/

And this is the command line:

gr_satellites JY1-Sat --wavfile JY1-Sat_satnogs_3154621_2020-11-17T11-39-53.wav --samp_rate 48e3 --f_offset 12e3

This seems to be related to --clk_limit are there any tips on how to find the right value?

@daniestevez
Copy link
Owner

daniestevez commented Nov 17, 2020

You're right. The problem is that the default clk_limit is too low for this recording (I think the recording station is at fault).

To debug this and find a value of clk_limit best suited to this particular recording, I suggest using the --dump_path option (which is described here in the docs) and ipython to plot the results. You can run gr_satellites from ipython, so everything can be done quite interactively. This

As an example of usage, I start ipython and then run gr_satellites like:

In [1]: !gr_satellites JY1-Sat --wavfile satnogs_3154621_2020-11-17T11-39-53.wav --samp_rate 48e3 --f_offset 11.5e3 --hexdump --dump_path .

(the ! is used to run shell commands from ipython rather than Python code). I'm using --f_offset 11.5e3 because the signal is really at 11.5kHz rather than 12kHz, as one can check with Audacity.

This produces several files in the current folder with the internal signals of the demodulator. In this case of a DBPSK signal, the most interesting is the clock recovery output, but since this is a differential signal and there is no carrier phase recovery, using differential decoding before plotting is helpful. I do

In [2]:  x = np.fromfile('clock_recovery_out.c64', dtype='complex64'); plt.plot((x[1:]*np.conjugate(x[:-1])).real, '.'); plt.show()

to read the file, and plot the differentially-decoded symbols. I zoom in on the graph and see something like this:

jysat_1

The constant parts around -1 correspond to the preambles of the packets. These are correct. But once the data starts I see that the clock recovery is losing lock, since I don't get symbols at +/-1, but something spreading in the middle (though it seems the clock recovery is trying to do the correct thing repeatedly).

Next I try a larger clk_limit by running

In [3]: !gr_satellites JY1-Sat --wavfile satnogs_3154621_2020-11-17T11-39-53.wav --samp_rate 48e3 --f_offset 11.5e3 --hexdump --dump_path .

I already see lots of packets being decoded, but this doesn't give me so much feedback about whether the signal demodulation is running perfectly now or just working barely. I plot again the output of the clock recovery (same code as above), and even without zooming in, I already see this:

jysat_2

In all the recording except near the beginning and the end the clock recovery is working very well: I only see +/-1, with not much noise nor indeterminate values in the middle. At the beginning and end the signal is much weaker, so the decoder has some trouble working. We could try to optimize some of the parameters to perform better in these areas.

If I zoom in to the central region as before, I see this:

jysat_3

These are a couple perfect frames. We see their preambles which are constantly -1, and then all the data that hops between +1 and -1 with no bit errors.

Now, what's going on with this recording? It is interesting to plot the clock recovery average symbol rate by doing

In [4]: y = np.fromfile('clock_recovery_T_avg.f32', dtype = 'float32'); plt.plot(y, '.'); plt.show()

This gives

jysat_4

Some knowledge of the demodulator internals is needed to interpret this. The signal is 1k2, and the demodulator decimates the samples to 12kHz and works at 10 samples per symbol. Therefore, we would expect a nominal symbol period of 10 samples per symbol. We are getting an average of 9.97 samples per symbol instead, as shown by this plot. This is a very large frequency error of 3000 ppm. No RF receiver should have such a large error. If your 2m radio had that error, when you tuned to 145.900 MHz you would get 146.339 MHz. Madness, right? Not even the worse RTLSDR or soundcard is this bad. You can get a really cheap crystal that is maybe 50 or 100 ppm off, but that's it.

So what's the problem here? No clue. Could it be a software problem? Maybe, but at least I'm glad we have the tools to debug this.

The default clk_limit is 0.02, so that won't let the clock recovery go below 9.98 samples per symbol. This explains the lack of decodes with the default value.

By the way, the fact that JY1-Sat puts out a continuous beacon is very helpful when analysing these things, since it is easy to plot all the recording. When the signal consists only of short packets then I usually crop a short piece of recording that contains one or two strong packets and work with that, since otherwise it is difficult to zoom in to the parts that contain the good packets.

Another note, now that I've gone through this carefully to try to explain it clearly, I realize that the clk_limit isn't working as I originally intended it to (and as is described in the --help). I wanted this to be a value relative to the samples per symbol, so that 0.02 means a 2% error. Having a relative value makes so much sense, because frequency errors are always relative.

So I guess I should make clk_limit work as a relative value and update its default to 0.004, since the default of 0.02 was found mostly using 9k6 signals with 48ksps recordings, and these run at 5 samples per symbol (and 0.02/5 = 0.004). That gives a maximum error of 4000 ppm, so this JY1-Sat recording would then work fine with the default value.

TODO:

  • change the semantics of the clk_limit parameter to be relative to the symbol rate

@daniestevez daniestevez self-assigned this Nov 17, 2020
@daniestevez daniestevez added the recordings Problems processing recordings label Nov 17, 2020
@janvgils
Copy link
Contributor Author

As always a great reply, I will try these options and tools.

Thanks Daniel.

daniestevez added a commit that referenced this issue Nov 18, 2020
This parameter was always intended to be relative to the baudrate,
but it was absolute (or rather relative to the sample rate) due to
a misunderstanding of how the corresponding parameter of the
Symbol Sync block works. In fact, it was documented as relative
in the --help.

Following discussion in #196 I noticed that it was absolute and
decided to make it relative to the sample rate, maintaining corresponding
default value for 9k6 signals. The default value now has a different
effect for all the other baudrates.
@daniestevez
Copy link
Owner

I have just pushed a commit to master making --clk_limit relative, so from my side this issue (which served me as a reminder to do this) can now be closed.

@janvgils
Copy link
Contributor Author

Thanks for the update, I will again try to get ipython activated on my Debian Testing, the packages are installed but there seems to be no binary or alias for "ipython"

@daniestevez
Copy link
Owner

That's very weird. The python3-ipython package doesn't contain an ipython binary neither in unstable nor in testing. I can't understand why. There must be some obscure reason, since ipython is a rather popular package.

You can always install ipython with pip or use python instead of ipython, but the drawback of the python interactive interpreter is that you can't run shell commands with !. You could always use os.system() to run gr_satellites or run it from another terminal.

@janvgils
Copy link
Contributor Author

To work around this I have created an alias.

alias ipython='python -m IPython'

@daniestevez
Copy link
Owner

Perfect! I'll proceed to close this.

@kerel-fs
Copy link

kerel-fs commented Nov 21, 2020

That's very weird. The python3-ipython package doesn't contain an ipython binary neither in unstable nor in testing. I can't understand why. There must be some obscure reason, since ipython is a rather popular package.

Yes, ther is such a reason: You have to install ipython3 to get the actual frontend binary, see also this:

This package contains the backend terminal shell for Python 3: for the actual frontend install ipython3.

@janvgils
Copy link
Contributor Author

Thanks a lot for that information, we will install that packages and go from there.

@kng
Copy link
Contributor

kng commented Nov 23, 2020

I have a few better observations since then, like this one https://network.satnogs.org/observations/3176286/
Also implemented automated upload of the resulting pictures as seen in the data tab.
One specific difference is that I have set ppm correction to a integer, in the previous obs above it had decimals, not sure how this impacts the results. The same sdr used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
recordings Problems processing recordings
Projects
None yet
Development

No branches or pull requests

4 participants