The place where random ideas get written down and lost in time.
Interesting comment here in an Adafruit guide:
“If you're new to wireless communication and want to use BLE to make a group of microcontrollers talk to each other, we recommend you STOP RIGHT NOW AND GO LOOK AT THE PACKET RADIO FEATHERS.”
What they call “Packet Radio Boards”, namely RFM69 modules or RFM95 Lora (19 kpbs at 100m / 500m line of sight respectively) in either 433 MHz or 900 MHz.
“Feather” is the Adafruit name for an ATmega32u4 that has an RFM69 module directly on it. The RFM module uses the 3 SPI pins (SCK/MOSI/MISO).
The antenna for the US 915 MHz is simply a 3 inch long wire.
Guides:
- Adafruit RFM69HCW and RFM9X LoRa Packet Radio Breakouts.
- Using the RFM69 Radio with “RadioHead RFM69 library” example. That library has a simple send/receive for a binary blob buffer.
(Future self comment: this, of course, is a bit Adafruit selling their own stuff… Although there’s merit in the suggestion above especially for people who feel stuck on Arduino for some reason, yet there’s an alternative to consider here: ESP-NOW on any ESP32).
2020-07-18 - Projects Status
Category DEVCurrent projects, in no particular order:
- Non-started un-ended research with OpenCV / ESP32-CAM.
- Interested in treating these as pages / research articles on the train site.
- Start with one such page for the “Layout Vision / Cam Proxy” one.
- Cab Engineer:
- Basic version was released on Play.
- Was not able to get Wear part distributed via Play.
- Turnout card does not scale well with many turnouts.
- Publicly available but not advertising it right now.
- Should list it on the train site.
- Quote Otter:
- Stuck in whatever-land.
- Randall:
- Nothing going on right now. Completed my “cam proxy” prototype.
- Conductor 2… limbo state. Want it. Tons of work to get there.
- Of interest:
- Circuit breaker for the Stockton Station
- One more LED for T150.
- Myriad more options like more block detectors, more turnout controls, and the whole Fairfield idea.
- Rig4j…
- Some gaming project.
So from all of that, what do I want to start with?
I’d say start with Godot and do something with it. It’s summer time.
Speaking of Godot, there are options: https://defold.com/about/ Defold, a “turn key game engine… Lua or C++”.
2020-07-15 - Track Detection & OpenCV
Category DEVAlthough this should be in its own research doc, here’s a summary of two separate things I’d like to get done with model trains image detection. There’s some overlap yet they are different.
The first research subject is automated mapping: given a static image, find all tracks in the image, and create a visual schematic map of the network. There are two possible representations:
- Tracks form single paths (both lines and curves) with node intersections matching the frog of turnouts.
- Track segments -- lines, curves, and turnouts.
The first part of the problem is finding tracks in an image.
- A track is defined as two parallel rails with perpendicular ties in the middle. An additional constraint is that rails always have the same distance. Some obvious complications arise when we have parallel tracks. Outlier cases such as heavily weathered tracks where ties are invisible could be omitted. The outlier case of road crossings should be optionally treated though.
- Turnouts may be more difficult to detect. One approach is consider them the intersection of tracks, using a pure path/node approach. Turnouts geometry can be complex (e.g. double slip, X crossings). A first approach could just detect the “typical” simple turnout cases -- yard ladders, single sidings, and simple crossovers.
- Elevation is expected to be a problem, as detailed below.
The second part of the problem is to be able to map a layout by taking a series of “aerial” pictures, mapping track on each picture, and then merging them by detecting the edge overlaps.
- One simplification is to get images that are as much “from the top” as possible. Some kind of perspective should be expected and corrected. However this erases elevation and would make it nearly impossible to detect.
- Eye-level images would not be ideal as perspective is distorted and can make tract analysis a lot more difficult. There might be some compromise e.g. 45 degree view that would make the track still visible yet elevation possible to account for.
The second research is detecting trains on the track.
Click here to continue reading...
2020-07-13 - Android dark mode
Category DEVAndroid development: what is needed to do a theme changer that supports light, dark, and system dynamic theming?
A good candidate is Seeds.
2020-06-05 - OpenCV and JavaCV
Category DEVJavaCV: Used in Randall’s camera proxy app to capture data from an RTSP h264 / MJPEG feed, and produce jpeg images or publish an MJPEG web (via a Jetty web server).
OpenCV: for the Randall camera proxy project, need basic motion detection.
Some good tutorials here: https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_video/py_bg_subtraction/py_bg_subtraction.html
Example in Python. Java API available here: https://docs.opencv.org/master/javadoc/org/opencv/video/package-summary.html
And in JavaCV it shows how to convert frames between the FFMPEG input and what’s needed by the OpenCV library using “Mat” and an OpenCV converter.
Update 2020-06-09: The “cam-proxy” project is working nicely.
One realisation: I picked up the JavaCV approach as it seemed easier to get started, and that paid off. However it’s worth pointing out that the generated fatJar is an impressive 760 MB!
That is quite a feat.
Looking at the APIs, do I need all of JavaCV, or could I use only OpenCV with its Java bindings? Let’s see which APIs I’m using here:
- JavaCV.FFMpegFrameGrabber ⇒ there’s an OpenCV specific one.
- JavaCV.FFMpegFrameRecorder ⇒ to generate the MJPEG stream. Alternative?
- JavaCV.2dFrameConverters + CanvasFrame ⇒ there’s an OpenCV one.
- OpenCV core: IplImage, Size, Rect, Mat
- OpenCV imgproc: resize
- OpenCV video: cvCreateImage, mediamBlur, createBackgroundSubstractorMOG2.
- Thus one question is whether it’s possible to generate the output stream (MJPEG or h264) using OpenCV and its Java wrappers, or is FFMpeg needed for that?
- Uncompressed fatJar size: 2,762,758,664 bytes
- org/ part of the jar: 2,227,823,156 bytes
- Opencv: 1,065,264,936 bytes
- lib/ part of the jar: 629,358,581 bytes
- Ffmpeg: 371,946,457 bytes
- Javacpp: 10,261,365 bytes
- Javacv: 921,733 bytes
- Jetty part: 318,8118 bytes
So essentially trying to only use OpenCV would likely not save that much. A huge part of the JavaCV package is indeed OpenCV and a quick look at the final Jar shows that it contains not only java wrappers but also hpp headers, some xml, and most important the jni+si native libs for a lot of architectures (e.g. armhf, armeabi-v7, arm64-v8a, x86, x86_64). If an effort was needed to trim the jar file, it could be by avoiding packaging these in the first place by removing all the arm ones (3 out of 5 archs).
2020-05-02 - Dagger and Libraries
Category DEVHere’s an interesting problem in Cab v2:
- Main app: Main app component.
- WiThrottle library: Lib component.
The design I want is for the library to be an extension to the main app. The library provides components/modules that the main app can use and inject. The library itself cannot use anything from the app (since it is app-agnostic).
In terms of components/scopes: the library is the outer component, and the app is a sub-component of the library. The app can use elements provided by the library.
When using component dependencies, which one depends on which?
- https://proandroiddev.com/dagger-2-part-ii-custom-scopes-component-dependencies-subcomponents-697c1fa1cfc
- https://proandroiddev.com/dagger-component-dependencies-for-library-development-e2df7ce68233
I think that means the app component has a dependency on the lib component.
This seems to work with some caveats:
- @Singleton @Component AppComponent // dependencies = { LibComponent.class }
Issue:
- At build time “dagger AppComponent scoped may not reference bindings with different scopes”.
- ⇒ Two ways to fix that: either remove all scoping info from the dependencies component and everything provided; Can’t even be in the same @Singleton. Obviously that’s not right.
- ⇒ Both components can have and likely should have different scopes. However the “root” component must provide everything explicitly by using getters in the component.
E.g.:
@Component LibComponent {
ExportedType1 getExportedType1();
ExportedType2 getExportedType2();
}
Etc
Module providers in the LibComponent are not exported to the dependent component unless explicitly stated that way. If something needs an explicit module provider, it also needs an “exporter” declaration in the component. If something is not explicitly exported by the root component, dagger will try to use the type as-is, notice the scope discrepancy and basically ask for either a different scope or an explicit provider if the object has no scope.
[win] d: t/dev/jadx … jadx-gui
select apk
prefs select deobfuscation
save gradle project in e: temp android apk
2020-04-20 - 3D Games
Category DEVIn the “game with train themes” department, it would be interesting to find an engine with actual already available resources to make one demo sample of either. One thing I could learn is the interaction model.
As far as 3D engines go, Godot seems like a viable choice for my needs. That or a full “do it yourself” LibGDX-based approach like I was trying for Tracks.
Eventually it all boils down to assets. That’s the key thing, and the one weakness I strongly have. Looking at both above: The train shunting puzzle is within my reach; except I’m not keen on the end result and thus consider not worth the effort going there; and the large popular game is out of my reach, the number of 3d assets being way beyond my abilities.
It’s also the same usual problem: I’m looking at a bunch of game demos, and realize I don’t really want to spend that much time to get that level of result (the usual 80/80 rule applies here). And I don’t want a me-too result either.
2020-04-11 - Cab Engineer “scripting”
Category DEVOne feature I miss with trains is scripting. Back in 2014 or 2015, I wrote a very simple cab command interpreter in python for JMRI, “cab3.py”.
I should add something like in Cab Engineer:
- Tie it with an existing throttle (e.g. for a specific DCC address)
- Or let the script change/mix engines.
- Be able to save / recall scripts.
- Also control turnouts.
- Introduce a mini-editor with a less cryptic language, and buttons to quickly insert language keywords.
- Make it line-agnostic so that the script can be one line or multi lines.
Random examples:
Label start
Throttle 537 speed +12 for 5s until B370 then speed 0
Reverse T330
F2 press
F5 on
Throttle 113 speed +12 for 2s
Speed 0
Speed -12 for 2s
Normal T330
F5 off
Throttle 537 speed -12 for 5s until B310 then speed 0
Loop start
Here each command is one keyword + one value, and the “then” keyword is a no-op.
A command like “for” or “until” would simply introduce a pause.
A “function press” would toggle it for a fixed time, e.g. 300-500 ms.
A logical extension is a “record macro” mode, that records the actions, generates the script, which can then be edited, saved, recalled.
Recalling a script would open a card on the recycle view with a status/run/stop. Running would “inject” commands in controllers, but not block the user. E.g. one could try to “beat” the system, or start/stop an engine during a macro run. Useful for things like horn/bell, or prevent a collision.
2020-04-07 - Cab Engineer
Category DEVA follow up to 2020-04-04 Cab Throttle aka “Cab Engineer”: Importing Cab Throttle source has been done. It’s called “Cab Engineer”, and as all the source from Cab Throttle + WiThrottleLib.
The project has been changed to be compliant with Permanent Service & notifications required by API 26+.
Next steps are:
- Add dagger support.
- Use my mini RxJava instead of the event bus.
- Add new features:
- Toggle turnouts. [added as of 2020-04-10]
- Recall previous DCC addresses.
- Recall JMRI roster.
- Some less important yet desirable features for me:
- Support Day vs Night modes (with a quick toggle change).
- Support “soft” consisting.
I may not do it in that order. E.g. dagger/rx are less useful than core new features.
Note that when I started it, WiThrottleLib was able to support 2 modes:
- “Single throttle protocol” with multiple sockets to JMRI, for JMRI < 2.
- “Multi-throttle protocol” with a single socket to JMRI, for JMRI >= 2.
Now that JMRI is in v4, I think the “< v2” support is… useless. I won’t remove it but I won’t extend it either. Things like roster & turnouts are only going to be added to the more modern part.
As for the name, I'm pretty sure I don’t want to tie it to the “DCC” name publicly, even though the current implementation is very DCC and JMRI centric. E.g. for addresses, only DCC specs are supported, with short vs long addresses.