codyd51
You can still absolutely deduce the fundamental with great accuracy via an FFT, but the approach is a bit more involved. The relevant research area here is called ‘fundamental frequency estimation’.
For an example of this, you can see this app I built that lets you give keyboard and mouse inputs via playing notes on a bass guitar, which are recognized over the microphone: https://github.com/codyd51/offkeyboard
In this case, I was meaning to refer to brute-forcing the Doppler-shifts and PRN phases of each satellite, not the orbital parameters themselves. The project in the OP is able to get a position fix in less than a minute because, if the subframe timings are convenient, you can retrieve the necessary ephemeris parameters from the subframes in that span (and down to as little as 18 seconds in ideal conditions, if my back-of-the-napkin is right).
GPS receivers will look for the 'strongest' PRN signal in the noise, so broadcasting louder than the (incredibly weak!) C/A signal is a valid way to jam or spoof GPS. It is, however, generally illegal for civilians.
GPS receivers operating with good practice do tend to try to mitigate this sort of attack, by (for example) ignoring signals with a too-high power level. It's a bit of a cat and mouse game, and there are academic papers exploring each side.
Lastly, GPS receivers also need to deal with interference from GPS itself! If GPS signals bounce off surfaces before reaching the receiver, the receiver might see two sets of GPS signals: one that arrived directly, and one that was scattered off a surface and arrives a bit later. This is called ‘multipath interference’, and part of what goes into making GPS receivers work well is mitigating multipath interference.
Re. slow TTFF, or time-to-first-(position)-fix on older hardware, this essentially stems from advancements in processing power.
Traditionally, GPS receivers would need to download the ‘almanac’ of all the satellites in view, which takes a minimum of 12.5 minutes (under certain conditions) due to the GPS data transmission format and speed. With modern processing power, though, receivers (including gypsum) can just ‘brute force’ the search space to find the in-view satellites, instead of using the hints downloaded over the air. This is the technique described at the end of Part 1.
Shortly after publishing my iOS 4 jailbreak last October[1], I got to work on my next hobby project: a from-scratch homebrew GPS receiver, which can solve the user’s location solely from billions of radio antenna samples.
I took a commodity SDR (alongside the Python standard library and numpy) and built a signal processing pipeline that can detect and track GPS satellites over many minutes, drop and pick up satellites as they come in and out of view, and precisely determine the user’s position and clock inaccuracy.
All told, gypsum can go from a cold start to a fix on the user’s position, and the precise time, in less than a minute of listening to the antenna. I went on a journey of learning how to detect and track satellite signals that are literally too quiet to hear, and I hope that some of the magic comes through in the posts!
After implementing this myself and walking the long road of getting it working, I’m left completely stunned by the brilliance of GPS, across so many axes. I hope you enjoy the read!
On a more personal note, I’ll be starting a new job next week which isn’t as amenable to publishing side projects, and therefore this will be my last publicly-published project for some time. I’ve had great experiences making and sharing projects on here, and I’m really grateful for the positive feedback that’s been shared!
To resolve this while maintaining the spirit of the design, I think two representations need to be kept: one for the rendered pixel data, and one 'out of band' representation (such as the textual data - you also highlighted this in your comment).
The idea is that, when the pixel buffer memory gets too large, some of it can be dropped. When it scrolls back into view again, it can be repopulated by the secondary representation. What I don't like about this is how it doesn't feel like it generalises well - you always need to be able to store the secondary representation, and have code to redraw it.
I think the concept you suggested is a really good one: just make sure everything that's drawn is its own 'encapsulated' widget with its own drawing logic, and you can ask it to render itself whenever that's convenient. I'm grateful for the input here, and think I will end up switching to this sort of approach in the future.
The other commenter is correct that the work loop typically revolved around booting a QEMU instance which ships my UEFI application. The main run script will regenerate an EFI filesystem that contains a fresh build of UEFIRC, then pass it to QEMU.
However, the overhead here can get a bit cumbersome when trying to build a GUI. I set things up such that the app could target either bare-bones UEFI, or a hosted environment that runs on my Mac. By flipping a build flag, my GUI toolkit would either draw directly to the UEFI-provided framebuffer, or would hook into my Mac's windowing system and receive/push events to that. You can see some of the overhead of this 'dual-target' approach in the app's entry point: https://github.com/codyd51/uefirc/blob/main/src/main.rs.
Parsing IRC messages also really doesn't need any accoutrements, so I developed those with a unit test suite running directly on my Mac - you can see part of that here: https://github.com/codyd51/uefirc/blob/main/src/irc/response....
The animations are made using a small animation system that I made for this post. This system has two useful properties:
1. It allows me to animate whatever property of the object I’m interested in (alpha, frame, etc).
2. It allows me to set up other work to be triggered when the animation has reached a certain completion threshold, which lets the animations flow into each other. This is how (for example) the grid lines ‘cascade’ in after each other.
The 3D animations are also primarily HTML canvases, and I used Three.js to place them as textures in a 3D scene. I have some logic to map the coordinate system of the canvases to the 3D scene, so that I can draw the connective tissue between the canvases and run animations that operate on objects both on the 2D canvases and the 3D scene.
An IRC Client in your motherboard
As a bit of a gag, I’ve made a graphical IRC Client that runs entirely in the UEFI preboot environment. It features completely overdone features such as TrueType fonts, a cursor, and GUI decorations.
I first started this project as I was getting a bit tired building a from-scratch GPS receiver, and wanted to make something relatively quick and lighthearted. As tends to happen, this took a fair bit longer than I anticipated at the outset!
A fair chunk of that time was spent on the visualisations in the post showing how scroll views are modelled and how they’re rendered to a static viewport. I really hope you enjoy them!
When I first began wanting to "stuff something in UEFI that really shouldn’t be in UEFI", my first instinct was a Twitter client. As it turns out, someone has already done a great job making this by using UEFI’s HTTP protocol! I therefore decided that whatever I made shouldn’t use HTTP at all, because that’s taken. I went with IRC since it sits on top of TCP and has the same social media feel that doesn’t belong anywhere near a preboot environment.