Over the next few days the spacecraft should move into a reconnaissance orbit, which is given in Wikipedia to be a 265 x 60000 km orbit (having a period of 2 days) with an inclination of 86.9 degrees. However, the last burn hasn’t lowered the apoapsis that much. The current orbit is approximately 280 x 84600 km (3.45 day period) with an inclination of 87.7 degrees. A possible reason for using the current orbit, which has been described as a phasing orbit, will be explained in this post after reviewing the data we have about the burn.

As I usually do, to compute the moment and delta-V of the burn I propagate the pre-burn and post-burn trajectories in GMAT using this script, and study the output in this Jupyter notebook. I obtain an intersection at 11:44:18 UTC, which is pretty close to the periapsis passage, so the data seems correct.

The delta-V vector in m/s using the Mars body inertial frame described in this post is

[-1.477, -1.912, 52.565]

This vector has a magnitude of 52.62 m/s. Assuming a dry mass of 2500 kg and fuel mass of 950 kg, this burn would have taken 60 seconds with the 3 kN thrusters, and spent 57 kg of fuel. Thus, according to our (somewhat crude) fuel estimates, approximately 900 kg of fuel remain now.

It is convenient to write the delta-V vector in the VNB frame whose axes are given by V, the velocity vector, N, the vector normal to the orbit (which is defined to point along the cross product of the radius and V), and B, the bi-normal vector, which is the cross product of V and N. The VNB coordinates in m/s are

[-50.406, 0.032, 15.104]

We see that most of the burn happens along -V as expected for a retrograde burn, but there is a significant component along +B. This is perhaps a bit unexpected. The effect of a +B burn is to move the periapsis backwards along the orbit, so that it would move to a slightly more northern latitude (the spacecraft descends from north to south on the periapsis passage). In fact, the periapsis has moved from a latitude of 10.03º N to a latitude of 10.25º N. This might be relevant for the discussion that comes below.

Now the good question is what is the reason for moving to this intermediate phasing orbit with a 3.45 day period instead of moving directly to the 2 day period orbit? I think there is a quite reasonable explanation, but we must first understand the purpose of the 2 day period reconnaissance orbit. This will be the orbit used by the spacecraft to map and survey the intended landing site, until the lander is released, which is expected to happen in May or June.

Therefore, it seems quite desirable to have an orbit whose periapsis ground track always passes over the landing site. This gives plenty of opportunities for gathering survey data and is also mandatory for the release of the lander, which is basically going to be done from the reconnaissance orbit (by first lowering its periapsis in a suitable manner). So all this makes me think that the quoted “2 day period” is actually 2 Mars sidereal days (a Mars sidereal day is 24 hours, 37 minutes and 22 seconds), since that would give a repeating ground track.

For this plan to work well, the periapsis of the the orbit needs to be at the correct longitude by the time that the 2 sidereal day orbit is entered. Otherwise the ground track will be repeating, but it will not pass over the landing site. Now, the longitude of the next periapsis of the current orbit turns out to be 111.3º E. In Wikipedia the coordinates of the intended landing site in Utopia Planitia are given as 24.748º N, 110.318º E. Note that the latitude of the site is somewhat higher than the latitude of the periapsis of the current orbit, so perhaps moving the periapsis north is desirable. This might (but only might) be the reason for the burn component along B.

So we see that around the next periapsis, which is going to be tomorrow 2021-02-23 at 22:31:37 UTC, the spacecraft will pass above the landing site. Given this circumstance, it can now enter the 2 sidereal day reconnaissance orbit, which will then have a repeating ground track that always passes over the landing site.

There is no magic involved in these adjustments. Coming in from the previous orbit last Saturday, when arriving to the periapsis it is just enough to adjust the apoapsis altitude (and hence the orbit period) in such a way that when the spacecraft comes to the next periapsis Mars has rotated below the orbit so as to place the longitude of the landing site below the orbit. The required period to do this will depend on the (signed) difference between the longitude of the periapsis where the burn is performed and the longitude of the landing site. Therefore, the name “phasing orbit” is completely justified. The purpose of the current orbit would be to wait until the rotation of Mars places the landing site below the orbit.

To see what the passage to the 2 sidereal day orbit at next periapsis would look like, I have made this GMAT script. By adjusting the delta-V of the periapsis burn, I have seen that a 40.9 m/s burn will give an orbit with a ground track that is very close to be repeating. This is shown in the figure below.

There is some degree of complication here regarding orbit perturbations. The plot above shows 14 days of ground track, and we see that at some point the ground track starts to slowly creep to the east. The propagator I’m using here is quite detailed: the 80×80 GMM-2B Mars gravity model, point mass forces for all planets and the Sun, relativistic effects, and an integration step of at most 50 seconds (no solar radiation pressure or atmospheric drag, though).

Something I haven’t understood completely is why the period of the orbit shown above is actually 162 seconds longer than two sidereal days. Forgetting about perturbations, the track of such an orbit would drift some 0.66 degrees to the west per revolution. However, if I try to adjust the orbit to have a period closer to 2 sidereal days, I get much more drift of the ground track than with this orbit solution. I don’t know if this is caused by perturbations or by numerical accuracy (perhaps related to the integrator). This is something that might deserve more in-depth study. In any case, probably the real-world orbit will need some degree of station keeping to correct for perturbations.

The apoapsis radius of this 2 sidereal day orbit is 61217 km (giving an apoapsis altitude of 57821 km), while the periapsis has an altitude of 282 km (logically, still close to the 280 km we started with on Saturday). Therefore, some care should be taken when quoting this as a 265 x 60000 km orbit. That can be slightly misleading, as it is not clear if 60000 km refers to the apoapsis radius or altitude.

To summarize, in this post we have shown that it is very likely that the purpose of the current orbit is to pass over the landing site at next periapsis on 2021-02-23 22:31:37 UTC. Then a burn would lower the apoapsis further to obtain an orbit with a period of 2 sidereal days that has a repeating ground track passing over the landing site.

]]>Since then, I have been intending to write a post explaining in detail the signal processing and publishing the recorded data. I must add that detecting Voyager-1 with ATA was a significant feat. Since November, we have attempted to detect Voyager-1 again on another occasion, using the same signal processing pipeline, without any luck. Since in the optimal conditions the signal is already very weak, it has to be ensured that all the equipment is working properly. Problems are difficult to debug, because any issue will typically impede successful detection, without giving an indication of what went wrong.

I have published the IQ recordings of this observation in the following datasets in Zenodo:

- Voyager-1 recording with Allen Telescope Array on 2020-11-14: scan 1/4
- Voyager-1 recording with Allen Telescope Array on 2020-11-14: scan 2/4
- Voyager-1 recording with Allen Telescope Array on 2020-11-14: scan 3/4
- Voyager-1 recording with Allen Telescope Array on 2020-11-14: scan 4/4

The observation was done between 18:30 and 21:30 UTC on 2020-11-14, when Voyager-1 was between 40 and 60 degrees elevation. Antennas 1a and 4g were used. These are two antennas having the older feeds described in this paper, which have lower performance at X-band than the newer feeds donated by Franklin Antonio, which are described here. The reason for choosing antennas with older feeds was to have two antennas having the same feed type, as that might simplify calibration for beamforming (which would become necessary if the signal was too weak to be detected with a single dish). At that time we only had access to antenna 4g with one of the USRPs used by the GNU Radio team, so we chose a matching older feed antenna to use with the other USRP.

The dual polarization signals from the antennas were taken to LO d in the RF converter board, which converted 8419.7 MHz down to an IF of 512 MHz. The IF was received and digitised with a USRP N321 and a USRP N320. The two X and Y polarizations of antenna 1a were routed to the two channels of the USRP N321, and the two polarizations of antenna 4g were received with the USRP N320. The LO of the first channel of the USRP N321 was exported and shared to all the other channels. GNU Radio was used to record synchronized baseband IQ data from the two USRPs at a sample rate of 960 ksps using `int16`

format.

In order to make beamforming possible later on with the recordings, interferometric observations of the compact calibrator 1733-130 were done. This source appears in the list of VLA calibrators, and it was near the position of Voyager-1 on the sky. These observations would allow us to calibrate the phase offsets between the two antennas if needed for beamforming.

The observation was organized as four 30 minute scans of Voyager-1 interleaved with 5 minute scans of the calibrator. Longer scans of the calibrator were done before and after the four scans of Voyager-1.

The signal processing of the IQ recordings is done in this Jupyter notebook, which can be found in my ata_notebooks Github repository.

The first step is to fetch the ephemeris data from JPL HORIZONS using Astroquery. I learned this library from Nick Foster, who has a similar Jupyter notebook to process Voyager-1 recordings done with ATA on 2010. We need the range-rate from the ephemerides in order to compute and correct for the downlink Doppler, which is shown below.

The a priori estimate for the spacecraft’s transmit frequency was 8420.432097 MHz. In order to take the downlink Doppler into account, the recording was centred at 8419.7 MHz, as mentioned above. The residual Doppler that should appear in the baseband data is as follows.

The signal will be detected in a sub-Hz FFT resolution bandwidth, so we want our Doppler correction calculations to have precision of mHz. Therefore, the range-rate data is fetched from Horizons in steps of approximately 8.6 seconds and linearly interpolated to a grid with 10 ms spacing. The carrier phase corresponding to the integrated Doppler is computed over this 10 ms grid.

Dask is used for parallel computation and on demand loading of the IQ data by chunks. Each of the 30 minute scans is processed separately. The first step in the signal processing chain amounts to removing the DC spike. This is done by grouping the samples in segments of approximately 0.5 seconds and subtracting from each segment its average.

Next, the average power per channel over all the 30 minute scan is computed. Each channel is divided by its average power in order to normalize the power, since each channel has different amplitude gains. Then, LHCP and RHCP polarizations are synthesised from the linear X and Y polarizations. To do so, the phase offset between the X and Y channels of each antenna is needed. These phase offsets were measured by receiving the RHCP X-band signal from Tianwen-1 at 8431 MHz earlier that day. The phase offsets are assumed to be the same at the receive frequency for Voyager-1.

The phase for Doppler correction is linearly interpolated from its 10 ms grid to each sample and applied in order to correct for Doppler. Finally, an FFT with a bin size of 458 mHz, rectangular window and no overlaps is applied to the data and average power spectral densities are computed per antenna, polarization and scan.

A preliminary step to assess the quality of the IQ recordings is to plot the power of each channel versus time. Since the signal is tiny in the 960 kHz bandwidth, this gives basically the power of the noise floor, which can change due to changes in gain, noise figure, interference, etc. Plotting the power can help us spot any obvious problems such as the sudden increases in the noise floor that we are seeing with some of the Chang’e 5 recordings.

Since each of the channels has a different gain, we normalize the power in each channel by dividing by the average power of that channel computed over all the four scans. This makes the power be centred about one, and gives the figure below. We see that the power variation is only of a few percent, so everything seems alright.

The first step in processing the Doppler corrected spectra is to perform a bandpass calibration to flatten out the bandpass frequency response. This is done by fitting a degree four polynomial to the average spectra of each antenna and polarization (ignoring the steep skirts at the edges). The figure below shows the uncorrected spectra and the estimated bandpass shape. The peak of the Voyager-1 signal can already be seen clearly in the LHCP signal from antenna 4g, and also in antenna 1a, albeit a bit weaker.

The bandpass calibrated spectra are show below.

The average power spectral density for the LHCP polarizations between both antennas is computed and transformed to significance level (units of sigmas) by subtracting one, which is the average noise power, and dividing by the standard deviation. We get the figure below, which shows a detection at a level of 13.2 sigmas at a transmit frequency of 8420430170.7 Hz. This frequency is close to the a priori expected transmit frequency, so we are confident that this detection is in fact the Voyager-1 carrier. Moreover, if the Doppler correction is disabled, the detection peak disappears completely.

The next figure shows the power spectra in each of the antennas and polarizations per scan. We see that there is a clear peak in the first two scans, the peak is weaker in the third one, and disappears in the last scan. The reason why the SNR decreases throughout the observation is not known.

The estimates of C/N0 for the first two scans are given in the table below. These should be taken carefully. They are coarse estimates, since the signal is weak. The C/N0’s for the last two scans are not given, since the signal is already too weak.

Antenna 1a | Antenna 4g | |

First scan | -8.5 dB·Hz | -6.4 dB·Hz |

Second Scan | -8.8 dB·Hz | -6.7 dB·Hz |

There seems to be a difference in performance of 2.1 dB between antennas 1a and 4g that needs to be investigated further.

Doing a link budget for Voyager-1 is not so easy, since we don’t have an accurate estimate of its transmit power. Perhaps, it’s better to work with the estimated received power shown in NASA DSN Now, which is around -156 dBm for a 70 m antenna (under bad weather conditions, the signal may drop to -161 dBm, as shown by Richard Stephenson in this tweet). Assuming the same efficiency, one of the ATA 6.1 m antennas should receive a power of -177.2 dBm. At a system noise temperature of 60 K (which is taken from this paper but perhaps too optimistic), the noise floor is at -181 dBm/Hz, so we should find the carrier at a CN0 of 3.8 dB.

It seems that the CN0 we measured is 10 dB below this estimate, so either there is something wrong with the estimate or there is room for improvement with the receive chain at ATA. This is something that we’ll need to look into in the future, by measuring the performance of the system in terms of noise figure, gain, etc.

Nevertheless, we have shown that it’s possible to detect with the current equipment the Voyager-1 carrier at a CN0 of around -7 dB·Hz. If the power spectrum is normalized so that the noise has unity power spectral density, and we use an FFT bin size of 500 mHz, the carrier will have a power of 0.4. In order to get a reliable detection, at say, 5 sigma, we need the noise standard deviation to be below 0.08. With a single antenna, this amounts to an integration of 312.5 seconds. Thus, we should be able to detect Voyager-1 in as little as 5 minutes, provided that there are no SNR drops as in the last two scans.

]]>The figure below shows the distances between the pre-burn and post-burn trajectories. Finding the minimum of this curve is the method that I use to find the time of the burn. The minimum is attained at 09:01:05 UTC. Since the burn duration was slightly longer than 2 minutes, the report of the burn start at 09:00 UTC seems quite right.

The delta-V vector was, in Mars body inertial coordinates and m/s,

[86.471, 28.957, 89.190]

The magnitude of this vector is 127.556 m/s.

As I remarked in the update at the end of my previous post, it turns out that we had underestimated the initial fuel of Tianwen-1 by some 900 kg. In that post the plane change took 146 kg of fuel, leaving 45 kg of remaining fuel. Therefore, I have now estimated that the amount of fuel before the plane change was 1100 kg, and that the spacecraft’s dry mass is 2500 kg. This gives a burn time of 150 seconds with the 3 kN thrusters, and a fuel consumption of 142.7 kg.

To understand the burn better, and compare with my planning calculations, it is useful to consider a reference frame formed by the following vectors: the unit radial vector \(\widehat{r}\), the unit vector \(\widehat{v}_u\) that points along the vector \(v_u\) that is the projection of the velocity \(v\) onto the plane orthogonal to \(r\), and the orbit normal \(n = \widehat{r} \times \widehat{v}_u\).

The velocity before the burn in this frame was

[23.303, 95.900, 0].

Note that the first component is the radial velocity \(\|v_r\|\). The delta-V written in this frame was

[-20.501, -83.515, 94.210].

This shows that the burn didn’t happen in the plane orthogonal to \(r\), and in fact most of the radial velocity was cancelled out, thus lowering and advancing in time the apoapsis of the orbit. With the pre-burn orbit, the apoapsis radius was 185153 km, and its time would have been 14:24:17 UTC. With the post-burn orbit, the apoapsis radius is 184930 km, and apoapsis passage was at 09:39:51 UTC, shortly after the burn.

The components of the delta-V in the \(\widehat{v}_u\) and \(n\) coordinates are quite similar to the VNB coordinates that I computed in my planning.

The angular momentum of the pre-burn orbit was 17735 km²/s, and the angular momentum of the post-burn orbit is 17572 km²/s, so it has been reduced by 1% in order to lower the periapsis altitude to 280 km. The angle between the angular momentum vectors, which I denoted by \(\alpha\) in my previous post, is 82.5 degrees, and the inclination of the new orbit is 87.3 degrees. This is very close to the 86.9 degrees given in the mission plan shown in Wikipedia.

The calculations for this post have been done in this Jupyter notebook and this GMAT script.

]]>This is a good moment to review the maths behind a plane change manoeuvre and compute what the manoeuvre will look like.

Basically, a plane change involves changing the direction of the specific angular momentum vector \(h = r \times v\), which is one of the conserved quantities of a Keplerian orbit, and is orthogonal to the orbital plane. Understanding a plane change in terms of the angular momentum shows that it’s best to perform the plane change at apoapsis, when \(r\) is largest, and so the same thrust force produces more torque, due to the larger lever arm.

If we perform a plane change at a certain point \(r\) along the orbit, the final angular momentum \(h_1 = r \times v_1\) will be orthogonal to \(r\). In other words, \(r\) must still lie in the final orbital plane. So the only thing that we can do is rotate the orbital plane along the axis \(r\). For a plane change at the apoapsis, we are limited to swinging the orbital plane along the line of apsides.

If we denote initial quantities with the subscript 0 and final quantities with the subscript 1, we have \(h_1 – h_0 = r \times (v_1 – v_0)\). For a plane change at apoapsis, \(r\) and \(v\) are orthogonal, and so we see that the change in angular momentum \(h_1 – h_0\) and the delta-V \(\Delta v = v_1 – v_0\) are related by a factor of \(\|r\|\) and a 90º rotation. Thus, it is possible to plan the manoeuvre with angular momentums, and then easily translate the result into delta-V. For the general case in which \(r\) and \(v\) are not orthogonal, a similar procedure can be applied, since we are only interested in the projection of \(v\) onto the plane orthogonal to \(r\).

Denoting by \(\alpha\) the angle between \(h_0\) and \(h_1\) and assuming that we only want to change the direction of the angular momentum but not its magnitude, we have\[\|h_1-h_0\| = \|h_0\| \sqrt{2 (1-\cos \alpha)}.\]

In order to compute the angle \(\alpha\), let us consider the following geometric scenario. Denote by \(\delta\) the angle between a certain vector \(h\) and the \(xy\)-plane, and by \(\beta\) the angle between \(r\) and the \(z\)-axis. Let us consider the rotation of the vector \(h\) about the axis given by \(r\), and let \(\gamma\) be the angle of the rotation that brings \(h\) into the \(xy\)-plane. Then we have\[\sin \delta = \sin \gamma \sin \beta.\]Applying this to \(h = h_0\), we see that \(\delta = \pi/2 – i_0\), where \(i_0\) denotes the initial inclination. Thus,\[\cos i_0 = \sin \gamma_0 \sin \beta.\]We can write the same equation for the final angular momentum \(h_1\), and since in this case we are interested in achieving a polar orbit with \(i_1 = \pi/2\), we obtain\[0 = \sin \gamma_1 \sin \beta,\]which implies \(\gamma_1 = 0\). In the general case in which the final orbit is not polar the calculations are more involved, but the same procedure can be used.

Now, the angle \(\alpha\) is basically \(|\gamma_0 – \gamma_1|\) (some care should be taken with the signs here), because \(\gamma_0\) and \(\gamma_1\) are rotations of the vectors \(h_0\) and \(h_1\) on the plane orthogonal to \(r\), on which both of these vectors lie, and so that the result of these rotations gives the same vector (namely the intersection of the plane orthogonal to \(r\) and the \(xy\)-plane). Therefore, a rotation of angle \(\pm|\gamma_0 – \gamma_1|\) transforms \(h_0\) in \(h_1\). In the case of a final polar orbit we have\[\sin \alpha = \frac{\cos i_0}{\sin \beta}.\]

A more direct method of calculation of the required delta-V is given in the Wikipedia article about plane change manoeuvres, but I think that this way of working can give more geometric insight, even if it is a longer procedure.

Let us now work with the orbit of Tianwen-1. For this planning exercise, I have started with my planning of the Mars orbit insertion burn. The initial state vector comes from before the burn (and was given in this post). I have adjusted the start of the burn to 11:52:55 UTC to match the timing we saw in AMSAT-DL’s livestream from Bochum (taking into account 641 seconds of light-time delay), and the duration of the burn to 888 seconds so as to give an orbital period very close to 10 days, as given in this official statement from CNSA about the success of the Mars orbit insertion. The period given there is certainly rounded rather than exact, but for this planning exercise we don’t need the exact period, since we are more interested in computing the required burn rather than in knowing exactly when is the apoapsis passage.

In fact, an error in the orbital period will give a proportional error in the apoapsis radius, and hence in the required delta-V, but all the remaining geometrical parameters will be very similar. It is important to remark that even though burning exactly at apoapsis minimizes the delta-V, the radius \(r\) changes quite slowly around apoapsis, so it is possible that the burn will happen several hours away from apoapsis, favouring other conditions such as groundstation availability. For this manoeuvre, unlike for the Mars orbit injection, timing is not very critical, so it is difficult to be sure of exactly when it will be done.

In GMAT, we can see that after Mars orbit insertion the angular momentum is 17658 km²/s, and the inclination is 11 degrees (matching the inclination of the incoming hyperbolic orbit). We still need to compute the angle \(\beta\) between the vector \(r\) at apoapsis and the \(z\)-axis. This can be done by using the apoapsis radius, which is 182602 km, and the \(z\) component of the position at apoapsis, which is -31427 km. With these values we get \(\beta = 100\ \mathrm{deg}\). Using the formula above we get that the angle \(\alpha\) that the angular momentum needs to rotate is 85.24 degrees. Note that this angle is larger than the change in inclination, which is 79 degrees. This always happens when the burn is not at the line of nodes.

The fact that \(\alpha\) is smaller than 90 degrees can justify that the plane change will be made in an ascending direction. A plane change to the same polar orbit but in a descending direction could be done by using \(-h_1\) instead of \(h_1\). In that case the angle \(\alpha\) would be 94.76 degrees, and so the burn will be slightly more expensive.

Using one of the formulas given above, we get\[\|h_1 – h_0\| = 1.354 \|h_0\| = 23916\ \mathrm{km}^2/\mathrm{s}.\]Dividing by the apoapsis radius, we get\[\|\Delta v\| = \|h_1 – h_0\|/\|r\| = 130.97\ \mathrm{m}/\mathrm{s}.\]

Now that we know the magnitude of the delta-V, the next question is how to write the delta-V vector. Usually these are written in a VNB coordinate frame. In this case, the delta-V will lie in the VN-plane, since \(v\) and \(r\) are orthogonal. Knowing that the angle between \(v_0\) and \(v_1\) is \(\alpha\) and that the unit vector \(V\) of the VNB frame points along \(v_0\), we see that\[v_1 = (\cos \alpha V + \sin \alpha N)\|v_0\|,\]so that\[v_1 – v_0 = ((\cos \alpha – 1) V + \sin \alpha N)\|v_0\|.\]

For Tianwen-1, we have \(\|v_0\| = 93.7\ \mathrm{m}/\mathrm{s}\), so the (V,N) coordinates of \(\Delta v\) are (-88.69, 96.37) m/s. Plugging these numbers as an impulse burn at apoapsis in GMAT, we see that the calculations are correct and the inclination of the resulting orbit is very close to 90 degrees, while the magnitude of the angular momentum has been maintained. The two figures below show the results of this impulse burn propagated to the next periapsis.

To compute the burn time \(T\) for a finite burn that achieves the required delta-V, we use\[T = \frac{v_e m_0}{F} (1 – \exp(-\|\Delta v\|/v_e)),\]where \(v_e = 3154\ \mathrm{m}/\mathrm{s}\) is the exhaust speed of the thrusters, and the thrust \(F\) is 3kN. This gives 153.12 seconds. To enter the finite burn in GMAT it is also necessary to compute the direction of the delta-V vector in inertial coordinates. The VNB frame can’t be used, since it will change throughout the burn. This is easy to do, by using the values of \(r\) and \(v_0\) in the Mars inertial frame in order to compute the coordinates of V and N in this frame. The resulting orbit after performing this burn has almost the same angular momentum as the original orbit and an inclination close to 90 degrees, showing that our calculations are correct.

The figures below show the finite burn. They are almost identical to those of the impulse burn. The finite burn is marked with a yellow trace, but this can’t be seen because the spacecraft travels a short distance during the burn, in contrast to the Mars orbit insertion, where the velocity was much higher.

This burn will spend 145.6 kg of fuel. According to our estimates for the fuel spent throughout the mission, only 45 kg of fuel will remain afterwards. This seems a bit low, so it is possible that our estimates have been too pessimistic, and the amount of remaining fuel will be closer to 100 kg.

Planning ahead, according to this article, the apoapsis will then be lowered to achieve a parking orbit with period of around 2 days, from which the lander will be released. Finally, the orbiter will move to the remote sensing orbit, which is an 8 hour circular polar orbit. Note that part of the information in that article seems outdated. It mentions that “Because the landing area is selected in the low-latitude zone”. However, the landing location is expected to be Utopia Planitia, at 46.7º N latitude. Therefore, in the article the parking orbit is depicted as low inclination, whereas for a landing at 46.7º N a polar orbit is better. Moreover, performing the plane change at the apoapsis of the capture orbit is less expensive than if it is performed later in the mission, with a smaller apoapsis radius.

With this in mind, the manoeuvres that remain in the mission can be accomplished without expending too much fuel. Even 45 kg of fuel would give 41.5 m/s of delta-V to the full dry mass of the spacecraft, according to the rocket equation. Additionally, at some point the lander will separate, substantially decreasing the mass.

It is possible (but no official information supports this idea) that the mission will use aerobraking as an inexpensive way to lower the apoapsis. In this case it makes sense to adjust the periapsis radius (i.e., to lower it in order to have significant drag) at the same time that the plane change is done. This amounts to making \(\|h_1\|\) a little smaller than \(\|h_0\|\). Putting \(\lambda = \|h_1\|/\|h_0\|\), we have\[\|h_1-h_0\|^2 = \|h_0\|^2 (1 + \lambda^2 – 2\lambda \cos \alpha) = \|h_0\|^2\varphi(\lambda).\]The function \(\varphi(\lambda)\) is increasing in \(\lambda\) for \(\lambda \geq \cos \alpha\). This means that a small decrease in periapsis in fact needs less delta-V than if the angular momentum was to be maintained.

The GMAT script used for the calculations in this post can be found here.

**Update 2021-02-15 09:45 UTC:** Apparently in our fuel calculations we had overestimated the dry mass of the spacecraft in about 1000 kg, and hence underestimated the amount of fuel at launch in nearly 1000 kg. This report gives a dry mass of 2500 kg (we used 3390 kg) and 2500 kg of fuel (we used 1530 kg). Thanks to 仙贝的红茶 for mentioning the report. Jonathan McDowell gave a launch mass of 4920 kg. Therefore, it seems that the spacecraft would have at least 900 kg more fuel than what I have calculated in this post and in previous tweets. With this in mind, the spacecraft has plenty of fuel left and aerobraking no longer seems a reasonable idea.

Wikipedia includes a mission planning image that seems more up to date than the article I have cited. According to that image, the inclination of the polar orbit would be 86.9 degrees, rather than the 90 degrees that I used in this post. The periapsis would be lowered to 265 km height at the same time that the plane change is performed. Next, the apoapsis would be lowered to give a 265 x 60000 km reconnaissance orbit. From that orbit the lander would be released around May or June.

]]>In the case of Tianwen-1 the signal was pretty strong even while the spacecraft was on the low gain antenna, and we could clearly see the change in Doppler rate as the thrusters fired up. However, in the case of Emirates Mars Mission the signal disappeared as soon as the spacecraft switched to the low gain antenna. In fact DSN Now reported a received power of -155 dBm with the 34m DSS55. That was a large drop from the -118 dBm that it was reporting with the high gain antenna. Therefore, nothing could be seen in the livestream waterfall until the spacecraft returned to the high gain antenna, well after the manoeuvre was finished.

Nevertheless, a weak trace of the carrier was still present in the livestream audio, and it could be seen by appropriate FFT processing, for example with inspectrum. I put up a couple of tweets showing this, but at the moment I wasn’t completely sure if what I was seeing was the spacecraft’s signal or some interference. After the livestream ended, I’ve been able to analyse the audio more carefully and realize that not only this weak signal was in fact the Hope probe, but that the start of the burn was recorded in perfect conditions.

In this post I’ll show how to process the livestream audio to clearly show the change in drift rate at the start of the burn and measure the acceleration of the spacecraft.

The idea with this post is that anyone can reproduce what I’m going to show. After all, the only data I’m using is the audio of a livestream that is recorded in Youtube. For convenience, I include with my code the segment of data I’m using, which is a 5 minute segment that starts 7850 seconds into the audio of the full video. If you want to start from scratch, you can use any webpage or application to download the audio of the full video, and work with that. In my case I used a webpage to download the audio in 320kbps MP3 format, then converted it to an 8ksps WAV file, and used SciPy to read the WAV file and extract the 5 minute segment.

In the figure below you can see the waterfall of the first minute of the 5 minute clip I cut. The spacecraft signal can be seen as faint diagonal lines between 700 and 800 Hz. They are quite weak and have some fading, but hopefully you can see them.

There is something that is convenient to remark about the Doppler correction system that was used at Bochum for the livestreams. First, the system used the trajectory of the the spacecraft, ignoring the burn, to compute the expected Doppler. Therefore, the expected Doppler computation would be quite good before the burn started, but as soon as the thrusters fired it would diverge more and more from reality.

Second, rather than constantly adjusting the tuning to correct for Doppler and keep the signal exactly centred, the system performed discrete jumps of fixed size with the goal of keeping the signal inside a certain band, roughly 350 Hz wide. This had the effect of creating a sawtooth wave in the waterfall and the audio. As the signal arrived to one edge of this imaginary band, the Doppler correction performed a frequency jump to put the signal at the other edge of the band.

This can be seen quite clearly in the livestream of Tianwen-1. At the beginning of the livestream, the drift rate was quite low, since the spacecraft was well away from periapsis. Therefore, the period of the sawtooth was long. As the spacecraft approached periapsis and the drift rate increased, the period of the sawtooth kept reducing until it was quite short right before the burn. However, note that the amplitude of the sawtooth (this is, the width of this imaginary frequency band) is always the same.

The next figure shows the waterfall of the audio when the burn starts. It is a bit difficult to see, but hopefully you’ll be able to see two or three lines at the left around 800 Hz, and then a couple of lines going up in steps and with less slope, near the middle of the image.

When the burn starts, the drift rate increases (i.e., changes from negative to less negative), since the retrograde burn accelerated the spacecraft towards Earth. As the Doppler correction keeps tuning in steps to correct for a more negative drift rate, we get steps upwards. This is the same that happened at the start of the burn of Tianwen-1. In that case the drift rate became almost zero, and then positive, since the thrust-to-mass ratio of Tianwen-1 is higher than that of Hope.

The resolution of the plots shown above, and those that come later is 0.98 Hz per FFT bin (FFT size of 8192 with a sample rate of 8ksps) and 64ms per time step (due to the use of overlapping FFT, and an advance of 512 samples per FFT).

In what follows, the idea is to undo the Doppler correction done at Bochum to join back the pieces of the sawtooth wave and also correct for the drift rate in order to get a signal of constant frequency that we may see clearly in a spectrum plot. To do this, we just need to create a sawtooth that has the same (or almost the same) phase, amplitude and period as the one that the Doppler correction created, and then use that sawtooth to control the frequency of a local oscillator with which we mix the audio signal. I have adjusted the parameters of the sawtooth by hand until I obtained something where the resulting signal before the start of the burn had a constant frequency and had no (or very brief) jumps.

The result of this correction can be seen below. We see the signal before the burn as a flat line at constant frequency, slightly above 800 Hz, and then the signal rising up as the burn starts. The vertical white line marks the moment in which the start of the burn happens, which is at 184.96 seconds into this 5 minute segment. The right panel contains the spectrum plot of the data in the left of the waterfall (to the left of the white line). The signal can be seen very clearly, with an (S+N)/N of about 5dB, which would give an estimated CN0 on the order of 3 dBHz.

If we now change the drift rate correction, we can make flat the signal after the burn. We see that the drift rate is not constant, but rather it increases slightly with time, so it is not possible to find a drift rate that makes the line totally flat. I have chosen a drift rate that makes the line flat at approximately 20 seconds after the start of the burn. The right panel shows the spectrum of the right part of the waterfall (after the white line). Again, we have some 5 dB of (S+N)/N.

We have seen how by correcting the drift rate the “corner” of the Doppler curve, which marks the exact moment in which the thrusters started firing, can seen in the waterfall, whereas with the waterfall of the original audio signal it was impossible to see this corner. The moment in which the corner happens corresponds to 2:13:54.96 into the video, which by looking at the timestamps that appear in the screen shown in the video we can associate with 15:41:38 UTC (with a precision of perhaps one or two seconds). Since the light-time delay for this burn was 637 seconds, this means that the burn started at 15:31:01 UTC. This matches the official report of a start at 15:30 UTC, because it is possible that ullage motors fired one minute before the main burn, as we saw in Tianwen-1’s TCM-1.

The drift rate before the burn is -19.5 Hz/s, and when the burn starts it changes to -8 Hz/s. Such a drift rate change gives a line-of-sight acceleration of -0.41 m/s². This is just the projection of the acceleration vector onto the line-of-sight. In order to compute the full acceleration, we assume that it happened along the velocity vector of the spacecraft (with respect to Mars), and compute the projection of the unit velocity vector and the unit line-of-sight vector to Earth at the start of the burn. This computation ignores light-time delays, but is good enough for our purposes, since the line-of-sight vector changes slowly enough. The projection is 0.86.

This means that we only see 86% of the total acceleration in the Doppler drift rate. Therefore, the total acceleration must have been around -0.48 m/s². This contrasts to the theoretical acceleration of -0.58 m/s² that 720 N of thrust (since the spacecraft has 6x 120 N thrusters) applied to 1250 kg of mass produce (here the mass comes from a dry mass of 550 kg and 700 kg of fuel, assuming that the probe already spent in mid-course corrections 100 kg of its initial 800 kg).

Working backwards, we see that the measured acceleration of -0.48 m/s² would correspond to a thrust of 594 N. In fact, while I worked out the planning of the manoeuvre on Twitter, I noticed that the publicly stated burn length of 27 minutes was way too long to achieve the target orbit with a thrust of 720 N. To have a burn of 27 minutes that gave me the required apoapsis altitude I had to use a thrust of 658 N.

Note that all these calculations about the acceleration are just estimates, since we don’t know exactly the mass of the spacecraft, and our estimate of 1250 kg could be wrong by up to 10%. In any case, I think it is always good to go through these calculations to show what can be achieved with simple Doppler measurements and to check that the signal we observed matches what we expected.

The calculations and plots in this post have been done in this Jupyter notebook. The data file with the 5 minute segment of the livestream audio is included in the same repository. The results that I have shown are intended to be easily reproducible. It is possible to run the notebook with the supplied data or to start from scratch by downloading the audio from the livestream video on Youtube.

Many thanks and great work to all the AMSAT-DL team for organizing the livestreams. These were quite popular and were fantastic for outreach, as a wide audience could gather around a spectrum display and ask questions about spacecraft operations and communications via the livestream chat.

]]>Until now, the state vector data has encoded the spacecraft’s Cartesian position (in km) and velocity (in km/s) in a heliocentric reference frame. It is not completely clear if the frame is supposed to be ICRF or MJ2000, since the difference between the two is very small (see Section 3.5 in this paper by Kaplan) to be able to distinguish them with the data at hand, but we have always been using ICRF so far for consistency.

Today we have noticed that starting at some point on 2021-02-08, Tianwen-1 is now transmitting state vectors using a different, Mars-centric frame of reference. We don’t have the exact moment of the change. The last heliocentric vector we received was

2021-02-07 23:23:03.744100 18791639.655712113 211029173.8782428 96492674.05965108 -21.108400067542537 4.768376820024702 1.8445381918644286

This vector was received with one of the antennas at Allen Telescope Array, which I used as a backup since Bochum was unable to track that day due to a big snowfall.

The first Mars-centric state vector was received by Bochum the next day, and is

2021-02-08 22:14:25.049300 -345203.0840200648 103420.7793506239 -15761.456419116437 2.409386271990221 -0.7794198288828312 0.12118319008153547

The change in the frame of reference is clear from the change in magnitude of the position vector. Ensuring that the Mars-centric state vectors are interpreted correctly is important to continue using the data accurately. In this post I give the assessment of the appropriate reference system to use.

The fact that this new frame of reference is Mars-centric is clear because the switch from heliocentric to Mars-centric is the obvious thing to do now that the spacecraft will soon enter Mars orbit, and because the magnitude of the vectors matches the spacecraft’s distance to Mars. The first candidate for the direction of the axes is ICRF. However, this doesn’t match.

Another good choice is what GMAT calls the “body intertial” frame (see Section 2.6.11 in GMAT’s Mathematical Specification). This frame uses a celestial body, Mars in this case, to define the axes. The z axis points along the spin axis of the body at the J2000 epoch. The x axis points along the intersection of the xy-plane of the FK5 system at the J2000 epoch. The y axis completes the right-handed system. The spin axis data comes from the paper “Report of the IAU/IAG Working Group on Cartographic Coordinates and Rotational Elements of the Planets and Satellites: 2000” (behind paywall), which is revised every three years (see for instance the version for 2006).

The GMAT body inertial frame of reference gives a match for the Mars-centric state vectors transmitted by Tianwen-1, but the match is not particularly good, since the positional error is around 100 km. In what follows I assess whether it is reasonable to use the GMAT Mars body inertial frame to work the state vectors.

The idea in this small study is to take a state vector transmitted by the spacecraft (TM state vector), propagate it in GMAT to give a position track in a certain coordinate system, interpolate the positions in that track to the timestamps of a series of TM state vectors, and compute and plot the difference in positions. The first comparison that we do is to take the first TM vector received by ATA on 2021-02-07, propagate it, and compare it with all the state vectors received by ATA during that observation. The difference is shown below.

This plot is quite reasonable. Since the observation is short, we see differences of a few metres, caused by time quantization and by the fact that the GMAT and the spacecraft propagators are not exactly the same. We see two discrete jumps in the TM state vectors slightly before 22:30 UTC. These are common, and we don’t know exactly what causes them.

It is important to note that here the difference is particularly small because the observation only lasts 2 hours and 30 minutes. When propagating from day to day it is normal to see an error building up to a few km, specially after a manoeuvre, as the Chinese DSN perform orbit determination and compute and upload updated vectors to the spacecraft (see this post that describes what happened after TCM-3). Keep in mind that TCM-4 happened only a few days ago.

Next we take the same propagated trajectory (which uses a Sun-centric state vector as seed), make GMAT output Mars body inertial coordinates, and compare those with the TM state vectors received by Bochum on 2021-02-08. The results are below. The position difference is 136 km, which requires us to be careful before giving the body inertial interpretation as valid.

Since the change in the difference cannot be seen due to the scale of the plot, it is a good idea to remove the average and plot again. Now we see that even though the overall position is 136 km wrong, the “shape” of the trajectory only differs by a couple km.

The position error may be caused by a number of factors. First of, the difference between ICRF and MJ2000 coordinates (around 16 milliarcseconds), as seen from the Sun at the distance of Mars is on the order of 15 km. Second, different versions of the JPL DE planetary ephemerides may give slightly different positions for the Mars barycenter, though I am not sure about the magnitude of the differences. GMAT R2020a is using DE405, which dates back to 1997. Finally, we have the uncertainty in Tianwen-1’s orbit itself, since TCM-4 was performed a few days ago, so the orbit solution transmitted by the spacecraft is not final and may jump several tens of km.

In any case, it is pretty clear that the centre of the reference system is Mars barycenter (what other point that is at some 100 km from the Mars barycentre could it be?). Once the spacecraft is inside Mars Hill sphere, fundamentally we only care about the position of the spacecraft with respect to Mars barycenter in order to propagate its orbit. The directions of the coordinate axes are not so important. They only come into play when computing perturbations, such as the forces of other bodies in the solar system, or the effect of Mars non-spherical gravity field, or when checking if the spacecraft is behind Mars, as seen from Earth. As such, it is desirable to get the directions of the coordinate axes right, but a small error is not very noticeable.

A position error of 136 km, at the spacecraft’s distance to Mars, represents an angular movement of only 0.02 degrees. Therefore, even if the state vectors used a slightly different definition for the Mars spin axis, or for the direction of the x axis, the difference would be a small rotation.

Following this way of thinking, we separate the position error into a radial difference (the difference of the magnitudes of the vectors) and an angular difference (the angle between the vectors). The radial difference is shown below. It’s only 21.8 km.

The angle difference is around 0.021 degrees.

Therefore, my conclusion is that it is reasonable and acceptable to use these new Mars-centric state vectors with the Mars body inertial reference frame in GMAT. As a sanity check, we take the first of these Mars-centric vectors, propagate it in GMAT, and compute the difference between the GMAT track and the Mars-centric TM state vectors. The result is shown here.

The difference is very small, of a few metres. There is something a bit weird going on with the Y variable, but since we see jumps in the spacecraft’s TM vector track, this suggests that the very small problem is with the TM vectors themselves, and not with the GMAT track diverging.

The Jupyter notebook where these calculations and plots have been made can be found here, together with the supporting data.

]]>As usual, I have analysed this manoeuvre by propagating forwards the last state vector that we have from the spacecraft’s telemetry before the manoeuvre, propagating backwards the first state vector that we have after the manoeuvre, and finding the intersection point of the two trajectories.

This time the result is not very precise because of two reasons. First, the last state vector we have from before the manoeuvre is from 2021-02-02 23:33 UTC due to a problem with the telemetry reception in AMSAT-DL‘s Bochum observatory. Therefore, we need to propagate this state vector 2.5 days forward, whereas in other manoeuvres we had more recent state vectors. Second, this manoeuvre is a small correction, so the angle between the trajectories is small and finding their intersection is an ill conditioned problem.

The figure below shows the distance between the pre-burn and post-burn trajectories. The minimum happens at 10:47:51 UTC, which is quite far from the timestamp of 12:00 UTC reported by the media. The minimum distance is 2.4 km. There is no reason to believe that the media is not correct, since in other occasions the minimum was much smaller than 1 km, which already speaks about the bad accuracy of this method.

The delta-V vector in ICRF coordinates and m/s is the following. This should be quite accurate, even thought the time of the burn could not be found precisely.

[ 0.49150875, 0.29430668, -0.28538354]

The magnitude of this vector is 0.64 m/s.

The arrival trajectory can be seen in the figure below, which shows an orbit simulation in GMAT. The periapsis height is 408 km, and the inclination is 10.9 degrees. Note that the periapsis passage is almost exactly at 12:00 UTC. This is perhaps a coincidence, or maybe the result of deliberate and careful orbit planning.

The specific energy of the orbit is 3.10 km²/s², and the periapsis velocity is 5.36 km/s. For a capture orbit with a period of 11 days, as mentioned in this article, the required delta-V is 660 m/s. Assuming a specific impulse of 321.6 s (see this comment) and a thrust of 3 kN (this value has appeared published several times in the media), this delta-V will spend 836 kg of fuel over 879 seconds. Note that the delta-V that would be required for a parabolic orbit insertion (i.e., to obtain a specific energy of zero) is 614 m/s, so the capture into an 11 day orbit is only slightly more expensive. The spacecraft will move later into a parking orbit with a period of around 2 days.

The figure below shows an example capture orbit with a period of 10.69 days. It was obtained by burning retrograde for 889 seconds around periapis. The resulting orbit has a periapsis altitude of 293 km.

The calculations and orbit simulations used in this post can be found in this Jupyter notebook. Best of luck to CNSA with the Mars orbit insertion!

]]>One of the interesting things that have happened is the change to a lower baudrate in the telemetry signals. Until 2020-12-27 the baudrate was 4096 baud, while starting with the observation on 2021-01-02 we are seeing a new baudrate of 512 baud. This means that at some point around the end of last year the spacecraft was commanded to switch to a lower baudrate, to account for the increase in path loss caused by the increasing distance as the spacecraft travels towards the Sun-Earth L1 point.

The new baudrate gives an increase in Eb/N0 of 9dB, which is very helpful to continue decoding with ATA. In fact, using a single 6.1 metre dish and adaptive polarization, the signal is decodable with a some small link margin. Decoding is usually good, but can drop out when the noise level increases. Thus the change in baudrate suggests that the Chinese DSN is interested in tracking this spacecraft with smaller antennas. For instance, the 18 metre antennas at Qingdao and Kashgar should have 9dB of advantage over an ATA dish, and the larger antennas should have plenty of SNR to decode even the 4096 baud signal.

The change in baudrate is very clear in the spectrum of the signal. The figures below show spectrums obtained from the ATA recordings done on 2020-12-27 (4096 baud) and 2021-01-02 (512 baud). We see that the data sidebands are much narrower with 512 baud.

This change can also be seen in the waterfalls.

The framing of the 512 baud signal is exactly the same as before: concatenated CCSDS packets with a payload of 220 bytes. Therefore, each frame now takes 8 seconds to transmit. I have adapted my GNU Radio decoder and made a flowgraph for the 512 baud signal.

The figures below show the frame loss in the decoded frames (according to jumps in the virtual channel frame count). We can see how the 4096 baud signal gives occasional frame loss, while the 512 baud signal gives error free decodes except for some gaps on January 23 and 24, which are most likely caused by a sudden increase in receiver noise (as seen in the waterfalls above).

The decoded frames contain only data from virtual channel 1, which transmits real time telemetry. The data is very similar to that analysed in my previous post and mostly static, so it isn’t very interesting. I have updated the Github repository with the Jupyter notebooks containing the analysis of these frames. The repository also includes the data files with the frames. Additionally, I have updated the ata_notebooks repository with the polarization analysis of some of these recordings.

]]>Presumably this satellite uses “AX25, 9k6, GMSK”, as listed at the bottom of this page from Taiwan’s National Space Organization, and also in this research paper. However, this is not true. It’s simple to check that the usual 9k6 FSK AX.25 decoders aren’t able to decode this signal, and a look at the FSK symbols shows that there is no scrambler (9k6 AX.25 uses the G3RUH scrambler) and that the symbol sequence doesn’t have much to do with AX.25.

After some reverse-enginnering, yesterday I figured out how the coding used by IDEASSat worked, and today I added a decoder to gr-satellites to help Mike investigate what kind of telemetry the packets contain. The protocol is not very good, so I think it’s interesting to document it in detail, as some sort of lessons learned. In this post I’ll do so. As it turns out, the protocol has some elements that loosely resemble AX.25, so I’m left wondering whether this is some unsuccessful attempt at implementing standard AX.25 (we’ve already seen very weird attempts, such as ESEO).

An excerpt of the recording that Mike sent me can be found as `ideassat.wav`

in my satellite-recordings repo. From the recording, which is already FM-demodulated, it is clear that the modulation is 9k6 FSK.

The first thing that shocked me when looking at Mike’s recording is that there doesn’t seem to be any preamble. The packet starts directly with the data, as shown here. This is very bad, because closed-loop clock recovery algorithms need a preamble to lock to the symbol clock.

There is another bad thing about the FSK burst. If we look at the full burst, we see that before and after the burst there is a part that starts negative and slowly decays exponentially to zero.

This is caused by the fact that the FSK low tone is held for some 100ms before and after the FSK burst. Doing this at the beginning of the burst is a bad idea. Most FSK demodulators are AC coupled. Even the digital ones, as they use this to correct for frequency errors. So if one of the FSK tones is held for a significant amount of time, AC coupling will drive this tone to zero (just as we see with Mike’s recording). Thus, when the FSK burst starts, it will do so with a large DC offset, as we can see in the first figure.

In any case, all these problems can be sorted out (at least for manual inspection) by using a DC block in GNU Radio to correct for the DC offset at the beginning of the burst and Mike Ossman’s whole packet clock recovery script to extract all the symbols in the burst regardless of the lack of preamble.

After looking at the symbols for a while with NumPy, I realized that they were NRZ-I encoded UART-like data. By NRZ-I I mean the usual differential encoding from AX.25, where a 0 is encoded as a symbol change and a 1 is encoded as no symbol change. I say UART-like because it is exactly like 8-bit UART with one stop bit and no parity (1N8 for short) except for the fact that bytes are transmitted most-significant-bit first, whereas most UART transmit bytes in least-significant-bit first ordering.

The clues that lead me to this conclusion are the following:

- Differential decoding yields a richer autocorrelation than if we don’t do differential decoding; it’s always handy to see how differential decoding changes the autocorrelation
- After differential decoding, the autocorrelation showed peaks every 10 bits, and much larger peaks every 400 bits (which I’ll explain later)
- Arranging the symbols in 10 bit segments, there were two adjacent bits that had constant and opposite values; these strongly suggest the stop and start bits of UART
- The fact that the start bit of UART must be zero and the stop bit must be one indicates NRZ-I rather than plain differential decoding (the two are related by a bitwise inversion)
- When interpreting the UART bytes as most-significant-bit first, I got ASCII data

When decoded as NRZ-I 1N8 MSB UART, I got the following data in hex. The line breaks are mine for clarity and I’ve corrected a few obvious bit errors at the beginning by hand.

7e424e3043552030424e3049444130f000f4b2420741c3d042787fffdf021520000000000101007e 7e424e3043552030424e3049444130f001000101030401ffff07800720071807800728071800007e 7e424e3043552030424e3049444130f0020300670b0b0000000000000000089b04810cb8044b0d7e 7e424e3043552030424e3049444130f003b7035a032101a80cd802800cb80058176800080778007e 7e424e3043552030424e3049444130f00408071800080710fbf81fe000181fe001802f100000007e 7e424e3043552030424e3049444130f005000000000004f800004230424d46554e0000000000007e 7e424e3043552030424e3049444130f0060000000000000000000000000000000000000e6a00ba7e 7e424e3043552030424e3049444130f00707d0ff230c76f483d9cef5c2d4f0ad3047025d8100007e 7e424e3043552030424e3049444130f008271000002b14f81cf51afd00000000000000000000007e 7e424e3043552030424e3049444130f000f4b2420741c3d042787fffdf021520000000000101007e 7e424e3043552030424e3049444130f001000101030401ffff07800720071807800728071800007e 7e424e3043552030424e3049444130f0020300670b0b0000000000000000089b04810cb8044b0d7e 7e424e3043552030424e3049444130f003b7035a032101a80cd802800cb80058176800080778007e 7e424e3043552030424e3049444130f00408071800080710fbf81fe000181fe001802f100000007e 7e424e3043552030424e3049444130f005000000000004f800004230424d46554e0000000000007e 7e424e3043552030424e3049444130f0060000000000000000000000000000000000000e6a00ba7e 7e424e3043552030424e3049444130f00707d0ff230c76f483d9cef5c2d4f0ad3047025d8100007e 7e424e3043552030424e3049444130f008271000002b14f81cf51afd00000000000000000000007e

We see that the burst consists of 18 frames which are delimited by `0x7e`

at the beginning and end. These resemble the HDLC flags. However, there aren’t any other aspects of HDLC such as bit stuffing or the CRC-16. In fact, there doesn’t seem to be any CRC that can be used to discard frames with bit errors. Frames have 40 bytes, and begin in the same way, which explains the strong autocorrelation at lags of 400 bits and multiples (recall that with 1N8 UART we have 10 bits per byte).

Now, the beginning of the frames is ASCII for

BN0CU 0BN0IDA0

These are almost like the AX.25 destination and source addresses (with a SSID of 0) that occur at the beginning of the AX.25 header. However, in standard AX.25 these should be written in the 7 MSBs of each byte (so they don’t look like ASCII text), whereas in IDEASSat these are written in the 7 LSBs of each byte. I’ve encountered this misunderstanding about AX.25 address fields in other occasions.

After the two “addresses”, we have the byte `f0`

, which probably is the PID field with the *No Layer 3 protocol* value. However, the control field byte, which in standard AX.25 is placed between the addresses and the PID, would be missing.

After the “PID field” we have 23 bytes of what seems to be telemetry. We don’t have a description for the telemetry format. However, it seems that the first of these 23 bytes is a counter that counts from 0 to 8 and iterates through 9 different telemetry structures. Most of the telemetry values seem simple 8-bit signed channels, and structure number 5 contains the ASCII string `B0BMFUN`

. In this example burst, each of the two repetitions of each telemetry structure contains the same values. Probably this is always the case to increase the reliability.

So how does the IDEASSat gr-satellites deframer work? Well, first off, I don’t think that the protocol used by IDEASSat is very good for transmitting data over RF. In fact it is not robust at all, and bit errors will cause all sorts of problems.

Besides the problem of the lack of preamble, using UART over RF is never a good idea. The state machine that tracks start and stop bits is prone to fall into all sorts of traps because of bit errors (unless a very complicate state machine is used). Incidentally, using UART, with or without NRZ-I, guarantees a bit transition every 10 bits, so at least this is good for clock recovery.

The use of `0x7e`

to delimit frames can create a problem if that byte appears in the data (or even if it appears as a cause of bit errors). Finally, there is no means to check if decoded packets are corrupt.

I’m sure that with effort it would be possible to create a somewhat smart decoder for this protocol. Whole packet clock recovery could be used to prevent the problems caused by the lack of preamble. After NRZ-I decoding, the bits could be correlated against the expected UART start and stop bits for robust byte synchronization. If we use the fact that frames are 40 bytes long, then frame synchronization can also be made robust by finding several `0x7e`

bytes (maybe correlating against the 36 `0x7e`

bytes that we know should appear in an 18 frame burst). And finally the bit errors in the UART start and stop bits could be used as a heuristic of how many bit errors there were in the useful data, as a means to discard garbage frames. However, I don’t think it’s worth the effort. In the end, this protocol doesn’t have any FEC, and it is something ad-hoc used by just one satellite.

Therefore, today I decided to write a much simpler deframer for gr-satellites, with the goal of not investing much effort and having quickly something ready that Mike could use to start decoding frames.

The decoder in gr-satellites uses the standard FSK demodulator, which does closed-loop clock recovery with the Symbol sync block. The FSK symbols are NRZ-I decoded and then the sequence `00111111010011111101`

is used as a syncword. This corresponds to the UART encoding of `0x7e 0x7e`

, which is found at the beginning of all the frames in each burst except for the first one (which we are going to lose anyway because of the lack of preamble). That sequence is already 20 bits long, so it’s somewhat respectable as a syncword, specially if we don’t allow any bit errors.

After finding the syncword, we extract the 400 bits following the syncword in a PDU and then run a custom block that performs UART decoding. This is done in the most simple manner ever: since we are already byte aligned, the start and stop bits are thrown without looking at them. The size of 400 bits will give us 40 bytes at the output, which makes the next `0x7e 0x7e`

appear at the end of the frame (or `0x7e 0xff`

if this was the last frame in the burst). I figured out this was handy, to detect if the frames ever change from their expected size of 40 bytes.

With all this in place, the gr-satellites decoder is working, but care should be taken when analysing the decoded frames. Since there is no way to check for frame validity, frames with bit errors, and even with complete garbage, will appear in the decoder output. Checking that the beginning of a frame is the expected

424e3043552030424e3049444130f0

can give us some confidence about its correctness.

**Update 2021-01-26:** after receiving some documentation from the IDEASSat team, we’ve learned that there is in fact a CRC. The CRC algorithm is CRC16_CCITT_FALSE using the nomenclature of this online calculator, and it covers most of the useful payload data in each of the 9 frames. A single CRC in the last frame is computed over the data in all the frames.

As an example of this, if we take the 9 frames shown above and throw away the `0x7e`

flags, the AX.25 headers, and the byte indicating the frame number, we are left with

f4b2420741c3d042787fffdf02152000000000010100 000101030401ffff0780072007180780072807180000 0300670b0b0000000000000000089b04810cb8044b0d b7035a032101a80cd802800cb8005817680008077800 08071800080710fbf81fe000181fe001802f10000000 000000000004f800004230424d46554e000000000000 0000000000000000000000000000000000000e6a00ba 07d0ff230c76f483d9cef5c2d4f0ad3047025d810000 271000002b14f81cf51afd0000000000000000000000

The last 11 bytes are zero padding. Immediately before this comes the CRC, which in this case is `0x1afd`

. The first 4 bytes are a beacon counter and are not protected by the CRC. The remaining of the data shown here (starting with `41c3d0`

… and ending with …`f81cf5`

) is protected by the CRC.

I am going to improve the gr-satellites decoder by using an idea of Andrey Kopanchuk UZ7HO. The new decoder will sync off the end of the “AX.25 header” of the first frame (using the UART encoding of `4130f000`

as a 40 bit syncword), take all the frames following that syncword (using the known fixed size), perform UART decoding, reassemble the CRC protected data and check the CRC.

Many thanks to the IDEASSat team for getting in touch with us.

]]>This has led him to discover some signals coming from satellites on a Molniya orbit. After examination with the Allen Telescope Array of these signals, we confirmed that they came from wideband transponders (centre frequency around 995 MHz, 13 MHz width) on some of the Meridian Russian communications satellites (in particular Meridian 4 and 8, but also others).

These transponders show all sorts of terrestrial signals that are relayed as unintended traffic through the transponder. By measuring Doppler we know that the uplink is somewhere around 700 or 800 MHz. We have found some OFDM-like signals that seem to be NB-IoT. Unfortunately we haven’t been able to do anything useful with them, maybe because there are several signals overlapping on the same frequency. We also found a wideband FM signal containing music and announcements in Turkmen, which later turned out to be the audio subcarrier of a SECAM analogue TV channel from Turkmenistan.

A few days ago, Scott detected a pulsed strong signal through the transponder of the Meridians at a downlink frequency of 994.2 MHz. He did an IQ recording of this signal on the downlink of Meridian 8. It turns out that this signal is a BPSK pulse radar. In this post I do a detailed analysis of the radar waveform using this recording.

As a first step, the `meridian_pwr.grc`

GNU Radio flowgraph is used to compute average power in windows of 100 us. The results of this are plotted below. The figure shows strong pulses appearing every 10 seconds approximately.

If we zoom in to any of these pulse we see that in fact it consists of a train of very short pulses. At a 100 us resolution, the pulses only last two time bins.

To obtain more resolution, it is appropriate to work directly with the IQ data. Since the full one minute recording is large, we work only with the first pulse train. After some careful analysis, it turns out that the pulses can be folded neatly by using a period of exactly 1570 us. However, when folding by 1570 us we see that the pulses actually happen at three different positions.

This is called pulse staggering and it is pretty common in radar. The figure below shows the staggering more clearly. Here each line represents a 1570 us period. We can see the three different pulse positions, which follow a very regular pattern. It is also noteworthy how the pulse train fades in and out.

Zooming in to one small piece of this image we see more clearly the pulse staggering pattern. The offsets of the pulses follow the repeating sequence `[0, 1/2, 3/2, 1/2, 0]`

, where here one unit is approximately equal to the pulse length.

Next we analyse one of these pulses separately. If we compute the square of the signal we see that its spectrum has a strong CW tone. This suggests that the pulse is BPSK-modulated. The frequency of the tone allows us to recover the suppressed carrier, which is at approximately -91.7 kHz in the 2Msps IQ recording. The cyclic autocorrelation function has a cycle frequency at nearly 800 kHz, which indicates that the baudrate is 800 kbaud. Using this data we can perform carrier and clock recovery manually and obtain the BPSK symbols. The image below is the final result, and shows the BPSK symbols in the I component, and noise in the Q component.

The BPSK constellation is a bit noisy, because the pulse doesn’t have a large Es/N0 (it’s around 10dB), and it is not so easy to tell exactly when the pulse starts and ends. To increase the SNR of the BPSK symbols, we can check whether all the pulses use the same sequence of symbols (this will most likely be the case for a radar waveform) and accumulate all the pulses coherently.

In order to perform this accumulation, the first pulse train is folded in 1570 us segments, and one of the folds that contains a stronger pulse is chosen as a reference (the 100th fold, actually). All the folds are correlated against the reference fold and then cyclically shifted to align them in time with the reference and multiplied by a complex phasor to align them in phase. Then all the folds are summed coherently. The result is shown below. We can see a strong BPSK pulse in the I component, and some of the BPSK signal leaking into the Q component because the phase alignment wasn’t perfect.

If we zoom in to the BPSK pulse, we clearly see the BPSK waveform

Clock recovery is performed again manually, obtaining the symbols below, where now it is very clear where the pulse starts and ends.

The symbol sequence can now be extracted without errors. The length of the sequence is 170 bytes and its contents are shown below. Note that we have a 180º phase ambiguity that we are not able to solve, so it is quite possible that the waveform designers considered the same sequence but swapping the 0’s and 1’s.

000101010101000010110100111101011000010100011111111000001 111001111011101001000111001111111011001100001011010011011 01010110001011110001100111011101100000010011110111110011

As a consistency check, and to show that all the pulses indeed have the same sequence, I checked that the sequence decoded from the single pulse shown above coincides with this sequence exactly (so in fact we were able to demodulate the single pulse without bit errors).

The autocorrelation of this 170 bit sequence is shown here. It is noteworthy that the sidelobes near the main peak are very small. Random sequences usually have worse sidelobes than this, so I think that this is a sequence optimized for this property.

Small sidelobes near the main peak are an important property for radar because the sidelobes decrease the resolution for estimating the target range, and for discerning separate targets at similar ranges. Constructing long sequences with small sidelobes mathematically is a difficult problem (see Barker codes), so these sequences are usually found by search and optimization methods.

A quick and easy method to build sequences having good autocorrelation properties is to use maximum length sequences. These are optimal for circular autocorrelation, but not so good for linear autocorrelation, which is the important property for pulse radar. Maximum length sequences have several interesting properties. One of them is that a maximum length sequence of length \(2^n – 1\) contains, as subsequences of length \(n\), all the possible \(n\)-bit subsequences except for the sequence that consists of all zeros. Moreover, each of these \(n\)-bit subsequences appears exactly once. (One should consider the maximum length sequence cyclically when taking all its possible \(2^n-1\) subsequences of length \(n\)).

Using this property it is easy to check if a given sequence can be a subsequence of a maximum length sequence of length \(2^n -1\), just by checking if there are some two subsequences of length \(n\) that are equal. The 170 bit sequence of this radar has two 15 bit subsequences that are equal, so it can’t be a subsequence of a maximum length sequence of length \(2^n – 1\) with \(n <= 15\). This doesn’t preclude the possibility that the 170 bit sequence is a subsequence of a maximum length sequence with larger \(n\) (and in fact it will always be a subsequence of maximum length sequences with \(n >= 170\)), but it wouldn’t make sense to design a 170 bit sequence by taking a small subsequence of a large maximum length sequence.

Now that we have extracted the 170 bit sequence and the baudrate, we can generate the pulse waveform in GNU Radio and correlate it against the IQ recording. Since the correlation of the recording would be large (having the same length as the recording) but we are only interested in the correlation peaks produced by pulses, I have made a Python block that produces a sparse signal. This block only outputs signal samples whose amplitude exceeds a certain threshold, together with their position on the sample stream. In this way, the output file is very small, but the pulse position, amplitude and phase is preserved exactly. The GNU Radio flowgraph that uses this technique is called `meridian_corr.grc`

.

The figure below shows the amplitude of the correlation with the pulse waveform, as obtained from the sparse representation of the GNU Radio flowgraph output. We see something very similar to the figure at the beginning of the post, with pulse trains every 10 seconds or so.

The correlation peaks of the pulses span 5 samples, since the signal is sampled at 2.5 samples per symbol. Therefore, we use a peak find algorithm to extract only the peak of each of the pulses. An easy improvement of this algorithm would use interpolation to find the peak position more accurately, since it will typically lie somewhere between two consecutive samples. In the sequel, we work only with the pulse peaks.

The periodicity of the pulse trains corresponds to the sweep period of the radar. It is very likely that this radar sweeps a a narrow beam scanning 360 degrees of azimuth every 10 seconds, and only when the radar beam points towards the satellite (which is most likely near the horizon, as it happens with the Turkmen TV station) we see the radar pulses.

We can measure the sweep period more carefully, and it turns out to be 10.07 seconds. When we fold the plot with this period, all the sweeps lie neatly on top of each other, as shown here.

This figure shows other interesting aspects regarding the amplitude profile of the sweep. We can see some sidelobes, which would correspond to sidelobes of the radar beam. The asymmetry of the main lobe is also interesting. I don’t know why this happens.

The figure below shows the I (blue) and Q (orange) components of the pulse peaks. The IQ recording has been shifted in frequency to move the pulses to baseband using the frequency of the first sweep. As Doppler changes, the subsequent pulses show higher and higher frequency.

Next we study the pulse positions in detail. The figure below shows the pulse positions folded to the 1570 us repetition rate. We see three lines corresponding to the pulse staggering. The lines slope up with time because of the change in two-way range between the transmitter and receiver, and their relative clock drifts.

To study the staggering, we subtract the pulse positions of adjacent pulses to obtain the inter-pulse periods. We see that there are five different inter-pulse periods. These are 1330, 1450, 1570, 1690, and 1810 us. They correspond to a pulse staggering pattern of 0, 120, 360, 120, and 0 us. Above we said that the staggering pattern was, in some arbitrary units of size close to the pulse length, 0, 1/2, 3/2, 1/2, 0, so we see that one unit corresponds to 240 us. In comparison, a 170 bit pulse at 800 kbaud has a length of 212.5 us.

After correcting the folded pulse positions for pulse staggering, we obtain the figure below, where all the pulses are now neatly aligned.

The rate at which the pulse positions drift corresponds to a speed of 1409 m/s. At the time that the recording was made, Meridian 8 had a range rate of 336 m/s with respect to Scott’s station. Since the satellite was near its Molniya orbit apogee, the range rate as seen from other groundstations in the footprint would be similar to this, around 300 or 400 m/s.

Thus, I believe that a good amount of this 1409 m/s drift rate is due to the transmitter and receiver clock offsets. I’m not sure if Scott was using a GPSDO reference for this recording, but probably the radar isn’t, as there is no need to clock very precisely a monostatic radar. The drift rate is 4.7 ppm, so this clock error is quite reasonable for a transmitter that isn’t locked to GPS. Therefore, I don’t think it’s possible to use the drift rate information to say anything about the transmitter location, because the range rate and the clock drift get mixed up in the observation equation (there is only one equation and two unknowns).

The plots and calculations in this post were done in this Jupyter notebook, which contains some additional figures. The repository also contains the GNU Radio flowgraphs and the data, except for the large IQ recording.

The recovery of the 170 bit BPSK sequence was loosely inspired by a write up from the people of the Cornell University GPS laboratory about the determination of the GIOVE PRN codes.

]]>