I’m exploring the use of Julia for controlling hardware in near-real-time fashion (for prototyping, can tolerate some occasional hiccups). I tried the PiGPIO.jl package, but it’s a bit slow (hundreds of microseconds per GPIO update), so I used ccall to call functions in libpigpio directly, which brings the speed up just a bit, to around 100 ns per gpio write! A few questions arose along the way:
I have to run Julia as root in order to use libpigpio, but jupyter isn’t happy running as root. Anyone solved this before?
Has someone done a package for libpigpio (for direct C function access)? If not, I may try to write a package!
I will have to set up my Raspberry Pi or my Jetson Nano.
Are you sure that you need to run as root to use libpigpio?
It looks like the pigpio daemon needs to run as root. Does the user code have to also?
Can you not change the permissions on the relevant devices? Forgive my ignorance of GPIO.
Maybe you can profile what is slow and fix it or open an issue to get some insides?
I don’t see any reason, why Julia shouldn’t reach the same performance, and seems like PiGPIO.jl is a pretty compact package, so it may be easy to fix.
Perhaps not relevant. There was an excellent presentation on Julia Robotics at JuliaCon 2018
As I remember the inner control loop executes in about a microsecond, in order to keep the robot upright. I have no idea what hardware was involved with that robot, but I doubt they would tolerate long delays.
Maybe following this group will give you some ideas:
I can test again in a few days, but using Julia via PiGPIO.jl, which interfaces via sockets, took several hundred microseconds per gpio write. Using Julia and ccall to libpigpio was mostly 100 ns per write. So just to be clear, in both cases I was using Julia at the REPL.
Using Julia and ccall to libpigpio was mostly 100 ns per write. So just to be clear, in both cases I was using Julia at the REPL.
Yeah I got that, but ccall’ing will use a C implementation, while PiGPIO.jl seems to be a pure Julia implementation, which I suspect could be equally fast.
Unfortunately, it may not be as relevant as you’d hope: the control loop we were working with for that project was around 1 millisecond: For a walking robot, our control loop is quite a bit higher-level than just GPIO, as that 1 millisecond includes things like setting up and solving an optimization problem to choose the robot’s joint torques.
I do agree that it should be possible to match C performance for raw GPIO, and I think a lot of the lessons we learned from the work shown in that talk would be relevant (careful attention to memory allocation, lots of BenchmarkTools and ProfileView, etc.).
I just read the “Robot Locomotion” case study. Awesome stuff. I’m not making robots but am working on embedded systems that use control loops running in your range of speeds (e.g. a few hundred per second) and am exploring options for prototyping. Writing/compiling/testing with C on a microcontroller is the old standard, but requires specialized environment and is slow (development-wise); Arduinos or pyboards let you move a lot faster, but have memory and speed limits and moving data on/off them is somewhat clunky. Julia on a Raspberry Pi is really a tantalizing option. The RT kernel is interesting and I’m also curious about how much benefit (if any) one gets from controlling CPU affinities. Lot’s of playing to do. Thanks!
My understanding of PiGPIO.jl is that it is pure Julia, but it’s communicating with pigpiod over sockets, such that you could be on different machines with different operating systems. That’s really neat, but I don’t need remote access and it means each access involves a bunch of networking stuff with wrappers and addresses and maybe interrupts (I don’t know anything about the network stack especially how localhost is handled). In contrast, ccall access to the libpigpio.so involves about 3 ARM instructions per gpioWrite call, the function call overhead, the bounds checking in gpioWrite, a single register write and the return from the function.