That's a reasonable idea, but unfortunately wouldn't work in my case since the simulation relies on a lot of scientific libraries in Python and I need the inversion to happen on the microcontroller.
When you say "coordinate descent" do you mean gradient descent? I.e., updating a potential pose using the gradient of a loss term (e.g., (predicted sensor reading - actual sensor reading)**2)?
I bet that would work, but a tricky part would be calculating gradients. I'm not sure if the Python libraries I'm using support that. My understanding is that automatic differentiation through libraries might be easier in a language like Julia where dual numbers flow through everything via the multiple dispatch mechanism.
Awesome, thanks! This is exactly the kind of experienced take I was hoping my blog post would summon =D
Re: computing M and s, does torch.quantization.quantize_qat do this or do you do it yourself from the (presumably f32) activation scaling that torch finds?
I don't have much experience with this kind of numerical computing, so I have no intuition about how much the "quantization" of selecting M and s might impact the overall performance of the network. I.e., whether
- M and s should be trained as part of QAT (e.g., the "Learned Step Size Quantization" paper)
- it's fine to just deterministically compute M and s from the f32 activation scaling.
Also: Thanks for the tips re: CMSIS-NN, glad to know it's possible to use in a non-framework way. Any chance your example is open source somewhere?
For my application I need just the translations and Euler angles. The range of poses is mechanically constrained so I don't have to worry about gimbal lock. But yeah, my limited understanding matches yours that other parameterizations are more useful in general contexts.
Author here. Lots of questions about precision --- in the article I calculated 0.6mm as the standard deviation of 200ms worth of phase measurements (n=124) while the slide wasn't moving.
I'd love to hear any advice/ideas re:
- approaches for figuring out what's currently limiting the accuracy (i.e., noise sources)
- the relative merits of averaging in time vs phase domain
I'm super impressed they built a 7 person business around this concept and have been going since 2011 (all while doing their manufacturing in Germany!)
Author here. I agree that the Rust embedded books are a nice read, and the idea of type state programming --- taking advantage of Rust's ownership and generics system to enforce at compile time transitions between logical states via "zero-sized types" --- is interesting and could be useful in some contexts.
However, that is not what is happening here.
P0 and P1 are distinct types because they are distinct hardware registers.
I think it's great that they're modeled as distinct types; the problem is simply that Rust makes it difficult to conceptually iterate over distinct types (regardless if such iteration occurs at runtime via a loop or at compile-time via an unrolled loop, as per Zig's `inline for`).
An aside about "type state programming": Microcontrollers have a lot of functionality packed into the pins (see the STM32 "Alternate Function" datasheet tables).
Trying to model all of that using ownership of zero-sized generic types would strike me as a "when all you have is a hammer"-type situation.
If a single pin switches between, for example, high-impedance, gpio low, and PWM output depending on what mode your firmware is in, I suspect it'd be a nightmare to pass owned types around Rust functions --- one would have a much easier time (and more likely to be correct) if they checked their design using something like TLA+ / Alloy or implemented the firmware using an explicit statecharts runtime like Quantum Leap's QP framework https://www.state-machine.com/.
First, we should be clear that this is my goofy hobby keyboard project --- if I was concerned about safety, I'd have written it in MISRA C or something =D
There are many things about this project that a compiler can't help me with. I had to read about all of the pinouts from a PDF, draw them on a circuit board, and then map those pins in the firmware.
The code only deals with that last part, and in this particular example I decided that it was safer on the whole for the code to be obvious (easy to read + compare with hardware schematic) than to go through contortions with types to make some things more checkable by computer but less-checkable by human inspection.
The main risk here is not passing the wrong value to this match, it's fat fingering the transcription from the schematic.
Author here. Both my Zig code and the Rust peripheral access crate model the pins as distinct types, which I think is correct --- the pins have different memory addresses and sometimes (depending on the microcontroller) distinct sets of controlling registers.
The tricky part in Rust is how to make things generic across distinct types.
Zig's comptime lets you sort of "duck type" it (but with compile-time checking that all of the methods exist, etc.), whereas Rust requires that you explicitly introduce a trait and implement trait methods across the types.
The embedded HAL crates do this with extensive use of macros, for example: https://github.com/nrf-rs/nrf-hal/blob/aae17943efc24baffe30b...
This solution makes sense given the constraints of Rust, but there's quite a cost in terms of compiler time and cognitive overhead to understand what is going on.
(Aside: I didn't use the HAL in my Rust firmware, that's a higher layer of abstraction; I only used the PAC crates.)
Author here. I considered the enum "solution" but found the match on usize tuples to be clearer because it requires less code. Introducing an enum doesn't help because it neither:
+ helps better model the domain: P0 and P1 are already device ports, wrapping doesn't clarify anything,
+ nor does it buy you safety; arguably I'd say it makes it less safe, since the real risk with this sort of code is that you fat finger when copy/pasting between the electrical schematic and the firmware, so by adding extra wrapping you further obscure the pin assignments.
Keep in mind that this project was a lark that Nicki (http://www.nickivance.com/) and I literally made in the back of a van for her exact use case.
My article is a fun writeup of the design considerations and challenges of an email-only UI. It's not supposed to be a marketing piece, to convince you to (not) use the service, or to pass moral judgment on anyone's preferred communication medium.
I should also point out that emailing the app a Slack token is the same as emailing it a password, since the token allows it to read/write messages on your behalf (which is, of course, the whole point). Sending passwords around via email has security implications, which I'm sure you (a thoughtful, attractive, and considerate HN reader) can come to your own conclusions about based on your personal needs and risk preferences.
Thanks for trying it out, and I 100% agree with you that it's helpful to "think through all the states that the application can be in".
I'd consider Sketch.systems a huge success if the only thing it achieves is teaching UX designers how to think of behavior in terms of states.
(And reminding programmers, since coding sometimes makes easy to skip thinking about states and just keep nesting callbacks =P)
Re: Syntax --- the spec language does support comments: all characters following an octothorpe (`#`) will be ignored.
One of the use cases we want to support is to make it easy to throw together an idea quickly, and then share that idea with a friend via URL --- just like you might using CodePen, JsFiddle, or Github Gist.
These terms let us do that. If you have specific concerns about this, you or your lawyers should feel free to email me at [email protected] and we can try and get 'em sorted.
Haven't heard from OP, but another person emailed me and the issue is likely because Finda relies on AVX2 CPU instructions for fast search. These instructions were introduced in 2012, so it's likely the OP was running on older hardware.
I'll add CPU detection to a future version of Finda so that it can fallback to slower, non-vectorized instructions.
For more background on product development about Finda, there are notes on my personal website here: https://kevinlynagh.com/datatron/
I started this as a UI research project to try and replace OS X Finder with a keyboard-only UI. A strong inspiration was the Helm Emacs package.
My initial prototype was in ClojureScript/Electron, and I was exploring far more features like inline preview, and a command/argument (verb/noun?) builder system.
However, after showing my prototype to a few friends, they were all much more interested in the fast search and window switching capabilities, so I decided to cut scope, focus the project on those features, and get something out the door.
This is my first Rust project, and I've been thrilled with the language and that community in terms of great libraries, documentation, and their willingness to help beginners like myself.
p.s. Sorry I'm late to the party, I pushed this blog post online immediately before going to sleep for the night =P
Author here, and happy that you're interested in the software itself rather than the implementation =)
I'll probably write a detailed post about file indexing, since it's pretty interesting from a technical standpoint.
I looked into spotlight (via `mdfind`) but it was too slow and I wanted to port to Windows/Linux later, so your speculation is correct: Finda has its own file walking and indexing mechanism.
It walks a user-configurable set of directories, but not in the background --- it's actually done every time you open Finda, so you only pay the CPU cost when you are actually using the program.
The index is stored in memory, and size is proportional to the number of files/folders walked.
However, Finda does respect .gitignore files, so you can exclude things you don't want to show up in the search results (or consume memory).