## Logic Toy – a logic simulation toy

I had an idea for a game, part of which needed a grid based logic simulation, so I wrote a prototype logic engine.  As these things tend to do, it kinda took on a life of its own.  The basic premise is that each edge of a tile (North, East, South and West) can be ONE of nothing, an input or an output.

While Wire “gates” (for connecting things) have only one input then can have multiple outputs to allow branching of a signal.  Cross or bridge gates allow a cross roads, keeping the horizontal and vertical signals separate.  Input gates are the only gate that you can interact with and act as the circuits inputs, you can toggle the state of the input by right clicking it.

While there are still some areas needing work, its already rather functional.  The four images above show a circuit with every permutation of its inputs.  The four logic gates at the top of the circuit (AND x2, NOT, OR) replicate an XOR gate.  As you can see the output matches the output of the XOR logic gate.  This shows that both the XOR gate and also a simple circuit combining different logic gates also works.

Editing a circuit is straight forward, as you can see from the picture, its just a case of selecting where the inputs and outputs are and what logic function should be used.

I’d be interested to hear feedback or ideas, grab it here Enjoy!

Proof 12+7=19!

## JavaFX with Ode4J (physics!)

Well I have to say I was quite disappointed when looking round for a pure Java physics library and I’m most grateful for the quality of Ode4j ! It seems to fit in quite nicely

Despite initial misgivings about lambda’s I have to say I’m now a convert!  Not just with JavaFX but take this example of doing a collision callback in ODE

Normally you’d do this…

```    public void partOfAnUpdateMethod() {
if (!pause) {
space.collide(null, nearCallback);
}
...
}

private static DNearCallback nearCallback = new DNearCallback() {
@Override
public void call(Object data, DGeom o1, DGeom o2) {
nearCallback(data, o1, o2);
}
};

private static void nearCallback (Object data, DGeom o1, DGeom o2) {
...```

Not quite as horrid as an anonymous class (embedded in a parameter) but still a little unwieldy! Using a Lambda you can instead do this… (Can you tell I’m not a fan of anonymous classes!)

```    public void partOfAnUpdateMethod() {
if (!pause) {
space.collide(null, (d,o1,o2)->nearCallback(d,o1,o2));
}
...
}

private static void nearCallback (Object data, DGeom o1, DGeom o2) {
...```

Now I know the syntax could be better -> doesn’t mean anything in English, and so makes it less accessible to the novice, but I know which code I’d prefer to read and maintain.

I ended up making a nice little PhysObj class to “weld” JavaFX and Ode4J components together.  It builds on my earlier JavaFX work and utilises my Pivot class so you can hang multiple visuals onto it and they will all be effected by the Ode4j body in the PhysObj.

Encapsulating a new shape type (for example a triangle mesh) is just a case of extending PhysObj and should (famous last words?) be fairly trivial, I’ve supplied three extended classes to encapsulate boxes, spheres and cylinders.

And speaking of cylinders I’m guessing this version (of Ode4j) is using the CCD collider by default as cylinders actually collide, and generally behave as you’d expect!  (but I guess that’s a problem from long ago) Indeed with just 24 iterations per step, the simulation was stable and well behaved with 50 odd primitive shapes in proximity enough to give plenty of collisions everything looks good and solid…

Updating the visual objects with their Ode4J counterparts was really simple too, while just copying the whole 4×4 matrix would probably have been more efficient I ended up just using the Ode4J bodies rotational quaternion and position…

One minor issue (and issue is probably a bit strong!) was that Ode4J’s quaternions and vectors don’t have named “gets” like getX,getZ etc but instead have get0(), get2() so I had guess which was W as some people use a W,X,Y,Z order and some use an X,Y,Z,W order… and it was late…

One thing JavaFX should do in future is allow for much tighter and lightweight frameworks and a lot less library path nightmares!

You can grab the full example code here jfxOde4j.tar.gz

Posted in Uncategorized | 2 Comments

## JavaFX gui in a 3d scene

Well one thing for sure I like JavaFX GUI coding! Its even easier to use than swing and as you can see above you can just drop a GUI into your 3D scene.  Its so easy to do I won’t even bother running through the code!

The gui just works responding to mouse events as you’d expect without having to do any transforms and/or injecting events as you might have to do when hacking some toolkits together :/ ….

In the sample code I’ve also added some extra matrix utilities the controls are as follows

Dragging rotates the view, holding down shift while clicking an object will show a little gui attached to the object that shows its position numerically (its not editable but it could be, and could actually edit the position easily)

Finally holding the right mouse button down moves the camera forward in the direction it’s facing

You can get the code here jfxGuiTest.tar.gz

## JavaFX 3D using a single matrix for transformations

There are some advantages to using a scene graph, but the way things are implemented in JavaFX can mean half a dozen or so transformations, ( an axis angle rotation for each axis and a translation at least!).  This is well and good, but many people have their own library of code, for example you might want to use Quaternions for your rotations, the easiest way I have found is to use a single affine matrix for each scene node (parented on the root of the scene).  This allows you to adapt your normal 4×4 matrix math routines to work with JavaFX.

I’ve put a few simple routines into a Pivot class, the idea being you add the pivot to the root of your scene then add your 3d shape/model to the pivot.  Once the pivot is set up you use its functionality to move and rotate your model.  Using a pivot for the scenes camera as well allows you to point the camera at any arbitrary point.  It seems a little odd that JavaFX is trying to hide the lower level stuff, yet its missing higher level stuff like making one node face another…

Lets look at some code!

```public class Pivot extends Group {
private final double[] idt={1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
protected Affine matrix = new Affine(idt,MatrixType.MT_3D_4x4,0);```

While the Pivot extends Group (so you can use it as a parent) you shouldn’t use setTranslateX etcetera but rather manipulate the matrix via Pivot methods (extending or modifying Pivot if needed)

Get and set position are obvious and operate on Tx,Ty & Tz ( elements 3, 7, & 11)

There are really only two example utility routines setEularRotation(double rx, double ry, double rz) and lookAt(Vec3d centre, Vec3d up) – obviously in a more real world finished class you’d have more routines than this!

Both these routines leave the translation component of the matrix alone and operate just on the rotational part (the upper left 3×3 patch of the 4×4 matrix)

The Affine class is a welcome addition to JavaFX allowing better low level control for much more flexibility.  However from what I’ve seen of material handling things might not be as easy – I’m currently investigating lower level material handling (access to shaders is a must in this day and age!) but thats a topic for another day.

You can get the full source here jfxTest.tar.gz – you’ll note that there is nothing in the lib directory all dependencies are covered by JavaFX so class path and library path problems are just a bad memory! (the build script is also much easier)

## JNA wrapping C libraries for Java the easy way!

While wrapping a simple library for C isn’t exactly rocket science, it has its issue and can be a pain, there are numerous build systems (many seemingly making it a more complex job) but often you find its just not fun!

A really nice alternative is to use JNA which allows you to write a wrapper coding solely in Java, there is a performance hit but this is often a moot point, for example even in a video game some libraries like GLFW might only need a dozen or so calls a frame, so if it takes a little longer its not a game breaking deal.  I might however consider keeping my JNI based GLES 2.0 wrapper as on a slow machine an overhead on potentially a hundred or so calls could have an impact.

While JNA has a lot of advanced features like direct coupling of C structures with Java classes and even handling callbacks, lets look at a very simple example to see just how easy it is…

```public static class GLFW3 {
static {
Native.register("glfw");
}

public static native int         glfwInit();
public static native Pointer     glfwCreateWindow(
int width, int height,
String title,
Pointer monitor,
Pointer share );
public static native void        glfwTerminate();
public static native void        glfwMakeContextCurrent( Pointer window);
public static native int         glfwWindowShouldClose( Pointer window);
public static native void        glfwSwapBuffers( Pointer window);
public static native void        glfwPollEvents();
}
```

Even for such simple use doing this in JNI would consist of some C code and a Makefile and hopefully an ant build script which would give you a target to generate the needed C header files… or you can write a few lines of Java…

Actually using these functions is fairly straight forward too

```window = GLFW3.glfwCreateWindow(640, 480, "Hello World", Pointer.NULL , Pointer.NULL);

if (Pointer.nativeValue(window)==0) {
GLFW3.glfwTerminate();
System.out.println("unable to create glfw window");
System.exit(-1);
}```

This is a piece of a simple test I put together to test JNA as you can see its simple to see whats going on and converting some C code that uses the library is fairly trivial.

To test out JNA I wrapped just enough functions from GLFW and GLES 2.0 to make a window with a flashing coloured background.

You’ll need libglfw.so and libGLESv2.so on your library path, but you could as easily use GL if your platform doesn’t have GLES available.

You can get the complete test here jna-test.tar.gz

## Wordclock build

Light is tricky to film! the bleed through isn’t as noticeable to the human eye and the words look more bright pastel than laser bright glowing! (I think I need a strong light source to film this!!)

First off, this is not a cheap way to make a clock, however what it will give you is a rather nice looking discussion point.  The project initially began when I stumbled on the Teensy 3.1 this is a great little Arduino clone, but built around an Arm chip instead of an Atmega chip.

Although the Teensy 3.1 is a very similar price point to an Arduino it has a number of advantages, aside from the raw speed 72Mhz (can run at 96Mhz!) compared with a typical Atmega clock speed of 16Mhz.  This is probably less important that you’d think for many projects but it is an indication of the step up.  A very nice feature is a built in real time clock – which is what inspired the idea for some kind of clock project, other features are less obvious like its internal DMA infrastructure (more on that later)

My initial prototype was rough and ready but it very much proved the point – working flawlessly for several months keeping great time.  The design was very simple, basically a simple print onto a transparency sheet (I actually doubled up because they were not as opaque as you’d have thought!) Using almost every pin and a whole mess of wires, only meant I had one LED per word, which didn’t quite do the job…

Looking round for an alternative lighting method, I decided on a strip of addressable RGB LED’s – These WS2812 usually come in lengths of one metre which contain 60 LED’s in total.  I’d already designed a grid of words, the grid ended up with 5 lines and rounding up, I could give each word one LED per two characters – this made for rows of a maximum of eleven LED’s meaning I ended up with a handful of spare LED’s (more booty for the component pile!) on the right you can also see the laser cut front stencil of words (told you its not a cheap project!!)

Printing out a template for the back of the enclosure helped with positioning the led’s.  The great thing about WS2812’s is that you can take a pair of scissors to them and have short runs separated but in the same string.  On the left you can see the five strings of LED’s for each line of text in the template. Once the LED strings were glued down I could then breadboard the circuit.

The circuit is very simple, basically consisting of an octal buffer transceiver as the Teensy 3V3 won’t drive the data inputs for the LED strings.  One important note is to be careful of the brightness of the LED’s even through paper they are quite bright – I even ended up using bits of printer paper as diffusers behind each word

Of course I couldn’t wait to get the front on the thing so I could see individual words illuminated!  I had to add some black electrical take inside as there was a little too much leakage of light from word to word – as the front will never fit 100% flush to all the dividers in the back there will always be some bleed through but that actually adds to the effect without distracting from which word is obviously illuminated.

With five strings of LED’s needing signal and power and various other bits of wiring I’ll be the first to admit the back could be a bit tidier ! Ideally I should have made some kind of enclosure for the circuit…

I added a string and some stand offs later so I could hang it on the wall without the wiring getting in the way.

A tiny bit of strip board is all that’s needed to hold the buffer that we’re using as a voltage level shifter, it also handily works to tie everything together. As we move on to look at the firmware for the clock it might be handy to refer to this circuit.

As previously mentioned the Teensy has an advanced DMA infrastructure, this is used to great advantage with the WS2812 library which means we can dump a new pattern to the LED chips with minimal overhead to the CPU.  While I only need 5 out of 8 possible strings of LED’s and one string only needs 9 LEDs not 11 – this isn’t a problem just leave them out!

I found it particularly useful to write and test specific C subroutines on my machine as it can be quicker and more convenient to debug a simple C function rather than repeatedly uploading to the teensy and debugging via serial messages…

The LED’s are indexed from left to right and then on to the next string so the first LED on the second string is index 11 (starting from 0 on the first string)  This means you can treat the 5 channels as one long string, which is what I did to scroll the colour gradients.  The colour gradient is produced by successively LERPing from one random colour to the next.  Each step of the colour scroll is done once every tenth of a second, so each colour takes a little under a second to scroll from top left to bottom right.

There is also some logic to sort out the correct grammar for the time as randomly words like minutes or O’Clock are omitted, for example the same time will sometimes be shown differently

FIVE MINUTES PAST NINE O’CLOCK

FIVE MINUTES PAST NINE

FIVE PAST NINE

Equally when quarter or half (past/to) are used you can’t show “minutes”

The logic is a little convoluted and rather than over complicate things I just made a bunch of IF statements to handle parsing the time.  I wouldn’t claim it to be anything like a master piece of coding but for what its worth I’ve made the code available and the template design for the front panel here… wordclock-files

There are two simple switches available for changing the time, one increases the hour and the other the minute, rather than increase in five minute steps it increases in just minute increments – this means a whole bunch of presses to set the time, but it does allow you to set the time a few minutes fast… This means as the time approaches for example half past it will show half past as you’d read the time to someone…

The switches trip interrupt routines and there is some timing to de-bounce a potentially noisy switch, so setting the time is independent of the code that handles colour scrolling and displaying the time.

UPDATE….

You know how a project is never finished !  While I’ll leave the clock as is for the time being looking back at the build there are some things I’d have done differently and some things I’ll be changing…

On the back side I’ll add a fence around the edge instead of two small hold offs, just so it will sit a lot more square to the wall!

The dividers for each word should really by attached to the template, while the position of the lights can be a little off – the dividers are not quite in exactly the correct position – an in fact if I were to re-design the front word template I’d make a little more room between characters…

The diffuser material (printer paper!) could be glued to the back of the front word template, also I’d put diffusers on the few dummy letters as they look darker than even unilluminated letters with diffusers.

So some more “tweaking” to do at a later date!

Posted in Uncategorized | 1 Comment

## OpenGL core profile – an introduction

OpenGL core profile is centred around OpenGL 3.2 and allows you to use OpenGL without the old deprecated stuff and as such is likely before long to be a common minimum standard for support.

There are some slight differences with GLSL if you’re maybe been concentrating on mobile shaders, but nothing thats too far beyond the pale.

Lets have a quick wander down the code and see whats what…

```#include "gl_core_3_2.h"
#include <GLFW/glfw3.h>```

The first thing to mention is I’ve used a code generator to make me a procedure loader to load up all the functions that appeared after OpenGL1.1 – why this isn’t done automatically when a core profile context is created, well maybe I shouldn’t expect “common” sense !

I used the generator here which both seems robust and should work OK on other platforms too (Although I could guess developing windows OpenGL applications is not a joyous experience!)

Next we have a very simple set of shaders to make up a simple shader program

```const char* vertex_shader =
/*01*/ "#version 150 core \n"
/*02*/ " \n"
/*03*/ "in vec3 vp; \n"
/*04*/ "uniform float u_time; \n"
/*05*/ "out float blank; \n"
/*06*/ " \n"
/*07*/ "void main () { \n"
/*08*/ " vec4 p = vec4(vp, 1.0); \n"
/*09*/ " p.x = p.x + (sin(u_time+p.y)/4.0); \n"
/*10*/ " p.y = p.y + (cos(u_time+p.x)/4.0); \n"
/*11*/ " gl_Position = p; \n"
/*12*/ " blank = sin((u_time+p.x+p.y)*4.0); \n"
/*13*/ "}";```
```const char* fragment_shader =
/*01*/ "#version 150 core \n"
/*02*/ " \n"
/*03*/ "out vec4 frag_colour; \n"
/*04*/ "uniform float u_time; \n"
/*05*/ "in float blank; \n"
/*06*/ " \n"
/*07*/ "void main () { \n"
/*08*/ " frag_colour = vec4 (0.5, abs(sin(u_time)), abs(cos(u_time)), 1.0); \n"
/*09*/ " if (blank<0) frag_colour = vec4 (0.5, abs(cos(u_time)), abs(sin(u_time)), 1.0); \n"
/*10*/ "}```

There’s not a great deal to say here, except do note that I label line numbers, although you might have to do a little maintenance – doing this is very helpful when shader compiling fails…

```    if (!glfwInit ()) {
fprintf (stderr, "10 ERROR: could not start GLFW3\n");
return 1;
}

// tell glfw we want the core profile
glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

GLFWwindow* window = glfwCreateWindow (640, 480, "Hello Triangle", NULL, NULL);
if (!window) {
fprintf (stderr, "20 ERROR: could not open window with GLFW3\n");
glfwTerminate();
return 1;
}```

I like to let GLFW do the heavy lifting and as you can see making a compatible context is no where near as painful as EGL can be!

```    glfwMakeContextCurrent (window);

fprintf (stderr, "30 ERROR: failed to load gl functions\n");
glfwTerminate();
return 1;
}```

Once we actually have a context created we can go ahead and load up all those missing function pointers.

The rest of the code such that it is – is very simple “ordinary” GL code, coming from GLES2.0 (mobile) arena, the shader is where a far bit has been changed and that you need a vertex array.

Enjoy!

## Raspberry PI 2 – first impressions

It was some time since I used my original Rasperry PI, as it had been gathering dust for a number of reasons.  The main reason was one of performance, as much as anyone might love the PI they cannot claim that at 700mhz browsing the internet on a PI is anything more that a turgid experience.

So you can understand when reading of a claimed six fold improvement in performance my interest was defiantly piqued…

I’ll start off with a round up of the good! basically the performance is defiantly there – to the extent that browsing the internet is actually practical.  The improved architecture (ARMv6 v’s ARMv7) and the increase clock speed to 1Ghz definitely make a difference, what makes less of a difference is the fact it’s a quad core.  While for heavy weight applications (multi core compiling, rendering etc) it will have quite an impact, for general desktop use, you are unlikely to be troubling multiple cores (at the same time)

Obviously this extra power comes at a price, namely power (the other sort!) you will defiantly require a decent power supply – (a good quality 2amp wall wart is indicated) – this meant for me that even with the power plugged into my lapdock, it just didn’t quite cut it.  This leads on to a useful feature – if the PI doesn’t have sufficient power you will see a small 4 colour icon in the top right of the screen.  This extra power requirement may well catch a number of people out but then there is always the option to underclock…

The thing that disappointed me most is the seeming lack of low level (open source) progress, for example the implementation of EGL / GLES only really allows for fullscreen rendering in X11, however from my experimentation it should be quite possible to have a small (hardware) overlay window on top and moving around with a blank X11 window, all this with no copying during buffer swaps.  While I was tempted to have a go at an X11 version of EGL / GLES the thing really putting me off is the lack of documentation for broardcoms API.  Sure you have *some* of the source code, and even a datasheet, but without proper docs its hard to guess how you’re supposed to do something new with the API (as opposed to following boiler plate examples)

The upshot of all this is that although I should be able to take a program I’ve written on my laptop targeting GLES2.0,  recompile it on the PI and it just work, alas this is not possible – you have to port from Linux to Linux and add platform specific code… (not a great thing to be encouraging people in education to be doing…)

So its a mixed bag, I’d really like to see the PI become an end to end open source solution (with work on reverse engineering the firmware) but Broadcoms marketing stunt about opening up the PI was somewhat disingenuous – being basically a bunch of RPC glue and stubs to call GPU binary blobs even the shader compiler is a binary blob!

So hardware performance – could do better but a great improvement

Open and cross platform compliant…. errrr NOT (still!)

When sending some SVG work to a laser cutter I stumbled on an interesting problem (where really there shouldn’t be one!)

Now you’d be forgiven for thinking that a vector graphics format using document units of mm (millimetres) couldn’t possible have any issue with scale from one package to another… Surely 1mm in Inkscape = 1mm in Adobe Illustrator = 1mm on Pluto!…. You’d think….

It turns out that Inkscape uses a DPI (whats DPI got to do with vector graphics anyway!) of 90DPI which is a size used a couple of times in the w3c SVG standard – of course since its mentioned a few times no doubt Chinese whispers on some forums will quote it as a law…

As far as I can tell there seem to be no way to change this 90DPI value – which seems odd but still….

On the other hand Adobe Illustrator has a hang back from the Mac days where all the screens used to be 72DPI (no doubt internally to MacOS there is some backward compatibility kludge regarding this size too (just a guess!))

The upshot is that if you open an SVG in Inkscape created with Adobe Illustrator you’ll need to scale it by 125% (90/72=1.25)

Of more interest to Inkscape users is creating a document that a Laser cutter firm can handle without problems…

Now because a stencil font can’t have isolated islands of material, for the project I was working on I ended up making the text myself manually with individual strokes grouped together.  The first problem with this is that my strokes were 3mm wide to show the discard area, thankfully laser beams are a tad finer than 3mm so I had to turn my strokes into outlines (these outline have to be rather thin too – more on that later)

If you have a group of stokes for a font, first combine then using combine in the path menu, this actually makes them one “object” rather than a group of individual strokes.  That done now with the combined letter selected, in the path menu use the stroke to path menu item.

Now you have a path for each letter you can disable fill and enable stoke paint (in the fill and paint side dialog) for the selected path. You will probably have to ramp down the stroke width but leave it something visible for now like 1mm so you can actually see it while fully zoomed out…

Once everything is done as an outline you are probably as well to put a box around the whole design that is the expected dimension for the whole material like for example 297mm X 210mm for landscape A4.

The last job is to scale the whole thing by 80%, but as this will also effect the stroke width we need to pre-scale the stroke width before scaling it (You could prevent scale from touching stroke widths in preferences – but this is probably not a good idea to keep this setting all the time).

A common width for Laser cutting paths is 0.01mm yes thats 100th of a mm !  However we need to pre-scale that first so 0.01mm x 125% = 0.0125, now don’t worry when you plug this value into the width as it will have seemed to round it up to 0.013 (but it seems to actually keep the correct value) Now when you select everything in the project and apply a scale transform of 80%  (Transform is in the object menu – it will open a dialog in the side bar) if you look at the stroke width it should be 0.01mm as intended.  There may be (probably is) a way to turn off or alter the value display rounding but I couldn’t find it!

Oh now we have our 80% scaled work with 0.01mm paths make sure its all pure red (RGBA ff0000ff) this is another common value in use to indicate a cut as opposed to a burn (or shade) when lasering!

Now hopefully your printer/cutter will find it easier to use your designs, but don’t forget to ask them to verify that the outside box has the exact physical dimensions you expect !

Many thanks to Amy of artisan model makers (UK) for her patience in allowing me to bat multiple files at her so we could work out what was going on!

## Kobo mini – doing without the official reader software.

The mini is a great ereader, I love the fact that its size makes it even more convenient than a pulp paperback, best of all I love that the internal boot media is a removable SD card, while its not a terrible inconvenience to use something like a bus pirate to modify a flash chip it is a fair bit easier to write to a removable device! additionally its a snap to upgrade, which if you’re going to mess with your Kobo I’d really recommend you do.

You need to be sure you can recreate and backup an original Kobo boot SD, then you can store the old SD card as a backup, as well as keep backup of the first 10MB of the disk, also an image of the first partition (at least!) and keep this separate backup on your HD.

Once you’ve made and tested your newly cloned SD card you can start modifying it.

First of all you want to install the launcher software you may be interested in some of the other software he bundles with the launcher and if you are using it regularly you might consider a donation…

Of course the bit we’re interested in is his port of coolreader (I can’t seem to find any source for his modifications which is a pity, but I’ll admit I’ve not looked too hard)

Coolreader is much better than it used to me and unlike the “official” reader its able to cope with large collections without slowing to a crawl, you may have to wait 10 secs or so if you open a file selection dialog in a folder with a few thousand or more files – but frankly I really should curate my collection better than just bunging most stuff in one general folder!…

Customization is a snap, for example I have the launcher “autoboot” straight into coolreader, changing screensaver images is very simple (images live in the sleep folder) and unlike the “official” reader the text actually fills the screen.  Just one small gottcha if you want complete control over how the document is displayed you’ll have to disable auto text formatting…

Assuming you’re happy with coolreader, and why wouldn’t you be! notice you get a whole screen full of text rather than large variable gaps at the top and bottom of the screen… (don’t worry about it being inverse – I’m trying it out for a while to see if I like it, you don’t have to!), the next step is to stop the “official” software from ever running (this is not obligatory but good riddance an’ all that!)

The boot sequence they are using is slightly none standard but thankfully simple to modify…

Most modification is in within /etc/init.d/rcS

First I commented out just the section that executes the updates (any hacks that use KoboRoot.tgz I install – and check – manually)

Next to go is the boot animation, frankly in the 3-4 seconds it takes to boot linux and the 3-4 seconds the launcher/coolreader takes to run its superfluous anyhow, so I couldn’t be bothered to kill it rather I simply commented it out

`# ( usleep 400000; /etc/init.d/on-animator.sh ) &`

My next modifications are all at the bottom of the file

```# disable the flashing led
echo "ch 3" > /sys/devices/platform/pmic_light.1/lit
echo "cur 0" > /sys/devices/platform/pmic_light.1/lit
echo "dc 0" > /sys/devices/platform/pmic_light.1/lit```

I found this from the boot sequence of xcsoar and stopping it here means while Linux is booting we’ll have some visual conformation via the power LED

```# run dropbear in background
( /mnt/onboard/.kobo/vlasovsoft/usbnet-silent.sh ) &```

Because I’m I want dropbear running all the time, I run a modified version of the usbnet script that comes with the launcher (more on this later)

finally we can run the launcher itself…

`/mnt/onboard/.kobo/vlasovsoft/launcher.sh`

Because the usbnet script isn’t being run by the launcher but by the bootscript it won’t have the environment variables set that it expects.  First copy and rename the usbnet.sh (so the original can still be used by the Launcher menu as normal) first we need to supply the ROOT variable, our first modification (of the COPY!) is at the top of the script

```# used during boot, only show msgbox if there is an error
ROOT=/mnt/onboard/.kobo/vlasovsoft
root=\$ROOT/usbnet```

last near the end of the script we just need to comment out the success message box

`    # msgbox "usbnet" "usb network started!"`