00:00:02.280
Welcome everyone.
00:00:24.800
Hi everyone, I'm Selena and this is my sparring partner, Michael. We're here today to talk about our journey with Ruby and Kickboxer.
00:00:29.460
That's right! Today we’ll be exploring the state of MRuby, JRuby, and CRuby. But maybe we should start with some background. I’m sure the audience is thinking to themselves, what’s Kickboxer? Is it some kind of new tool or library?
00:00:40.980
Yeah, you're probably right. So, Selena here is an actual kickboxer. I'm sure you'll remember that a few years ago, a worldwide pandemic broke out, and Melbourne, where we're both from in Australia, endured harsh lockdowns. This meant that Selena couldn't train with her usual sparring partners, so she came up with this crazy idea: why not build a sparring robot using Ruby?
00:01:04.260
That's right! A key part of training for combat sports is improving your footwork. I thought, well, I could take a drill that I’ve been using at the gym with my coach and create a robot where pool noodles essentially strike the athlete, requiring them to swiftly evade using their footwork.
00:01:32.100
I reached out to my friend Michael, who loves collaborating on projects and knows a bit about hardware.
00:02:00.420
Yeah, I love an opportunity to work on hardware. I started thinking about the various moving parts and whether there would be any potential blockers to this project. So let's break them down. We start with the actuator, which is the hardware device that Selena will be training with. For this, we could use a motor or a servo along with a simple microcontroller like an Arduino.
00:02:30.600
We'll probably want to control it remotely using Wi-Fi, so maybe use something like an ESP32, which is basically an Arduino with Wi-Fi. That should fit the bill perfectly.
00:02:43.020
But can we run it in Ruby? Quite likely! We can use MRuby, which is a lightweight implementation of Ruby specifically designed for embedded systems. It’s perfect for running a device like the actuator, which has limited resources.
00:03:02.640
Great! And if we want to control it remotely, we’re probably going to need some kind of server for the actuator to connect to. But will that run Ruby? Yes, it will! We’ll probably use CRuby, also known as Ruby MRI, which is Matz’s Ruby interpreter.
00:03:21.420
The server will receive data from the actuator and also communicate with a mobile device that Michael will be using to control the actuator. For the mobile client, we have two options: Android or iPhone.
00:03:44.520
But could we run that with Ruby? Android is a Java platform, so surely it can just run JRuby on it. JRuby famously implements 98% of Ruby, so if we write it in Ruby, it should run in JRuby because JRuby is just Java.
00:04:03.840
So in the end, I’d be sparring with a pool noodle to practice my footwork. This is going to be such a cool project! I can’t wait for it to all come together.
00:04:26.100
Me neither! Especially since I'll be on the other end, throwing out the attacks at you with a mobile app. All right! I think everyone gets it. They understand the plan. Let’s get started with the actuator. Our initial thoughts here were MRuby. We heard Yuji Okuda talk about this numerous times at conferences where he made a Wordle game using MRuby C and ran it off a Sega Mega Drive.
00:05:09.900
Back in 2020 at Rubicon for Australia, Paul and Tharn presented a voice-based smart home system using Sinatra and MRuby C, showcasing so many possibilities.
00:05:46.300
We came across the MRuby ESP32 application template, and it sounded like a quick start. But we soon found out it was not as simple as we thought it would be. It was quite the journey! We assumed we could just run ASDF MRuby and it would be installed on our device, but it turned out to be much more complicated. We had to go through many steps like copying C project files into Ruby source files and MRuby components.
00:06:11.200
Then we had to use the ESP-IDF (Espressif IoT Development Framework), which actually uses Python to compile the project. After all that, we could finally push our code onto the ESP32. Do you want to see a demo?
00:06:46.620
Yeah, should we look at a demo now?
00:07:05.639
But what we also have is an MRuby implementation, so let's just plug that in. There we go! Whoa! MRuby is so much brighter!
00:07:39.500
Cool! I'm sure everyone's interested in the story, but can we just look at some code?
00:08:10.500
Great idea! On the left, we have some straightforward ESP32 C or Arduino code. We define a pin, set the pin to be an output, and in an infinite loop, we set the output high for one second, low for one second, and repeat. That's blink.
00:08:51.400
How does this compare to MRuby? In MRuby, we can do all the same things with way less code. Well, it's only two lines less, but still less, right? Although it is very verbose and all the functionalities are really just hidden away in other classes.
00:09:13.700
This was enough to get a light flashing, but we actually had to do a little bit more to get it connected to a server so we could control it remotely. Should we do another demo?
00:09:39.300
Yeah!
00:09:41.660
All right! Over here, I have an MQTT server running. We’ll talk about that later. If I bring this to the terminal, we can see that we're running Ruby 3.2.1.
00:09:58.680
If I connect to that Kickboxer LAN and run our client, we'll see that it’s got an actuator. So one has been registered. As Selena plugs in the second actuator...
00:10:32.060
It's all good! Live demos! So at this point, we see an event log at the bottom saying these actuators are live. We’re waiting for a second one to show up. There’s the second one! So now there are two, and if I go down the arrow, I can move between them. If I kick that top one and press enter, we get... yes, a lot going on!
00:11:30.000
On the right, we've got the MRuby code; it's about one page, not too bad. On the left, we have the ESP32 C code: one page, two pages, three pages, four pages. Look at all that code!
00:12:19.500
Yeah, it's as if the Ruby code was petite and easy to understand, while the C code was really big and clumsy. So what's going on under the covers?
00:12:42.900
Well, in the C code implementation on the left, we need to check that the connection is there, poll, and do a few other things, whereas in MRuby, it just works, as we know it!
00:13:02.580
Then we need to connect to the server via mDNS (Multicast DNS). In the C code, it needs a separate lookup, but in MRuby, it just works with MQTT. Easy as that!
00:13:34.320
Here we’re looking at some of the code used to send the keep-alive message every five seconds. Again, you can see in the left C code, there’s a lot more going on to copy the data into buffers just to concatenate strings.
00:14:08.720
As you can see, the MRuby code is much more familiar and accessible for Ruby developers, allowing more people to be involved in writing code for IoT and hardware projects.
00:14:43.240
Every project needs a server, right? We all know how to use CRuby and servers like Rails and Roda, so we knew this would be a piece of cake! Except when we’re dealing with an IoT device with limited capabilities that needs to communicate with a server requiring minimal communications.
00:15:07.360
One such protocol is MQTT (Message Queuing Telemetry Transport). That’s right; MQTT is a message broker allowing messages to be passed between various systems in a publish/subscribe style.
00:15:23.780
This means our client could talk to our actuator. We looked around and found Eclipse Mosquitto, which seemed to just work!
00:15:52.100
It worked so well we didn’t even need any server code at all. What? No CRuby? No! There’s plenty of other talks on CRuby at RubyKaigi, so we presumed it was okay to just go with Mosquitto and have no CRuby in our project.
00:16:14.740
And that brings us to the mobile client using JRuby. We started off with the assumption that it would be super easy on mobile devices, but boy were we in for a surprise!
00:16:38.060
We thought it would just work: you know, write some code, hit run, and voila! But it turns out building a mobile client with JRuby is not that straightforward.
00:17:02.920
We began by writing the client in plain old CRuby, and it worked! It listened to the MQTT server for actuators registering and allowed us to activate the actuators remotely.
00:17:30.160
Do you remember this demo from before? Everything’s all powered up. Which way are we going? This way? Probably the other way.
00:17:54.420
This is the demo from before. The lights are flashing. This is CRuby! If I go to the other side, the other light is flashing. Cool!
00:18:22.740
As you can see at the top, it's running Ruby 3.2.1 and that’s through our MQTT controlling the actuators.
00:18:49.260
But we really wanted to build the mobile client with JRuby. Since this is a presentation about the state of all Rubies, we thought we could just switch the example code over to JRuby.
00:19:12.380
But did it just work? No! Not at all. With a few tweaks and changes in the libraries we used, we managed to get a version running with JRuby.
00:19:45.080
If I now switch over to the other tab, was it command two? Yep! There we go! And we run. Well, you can see that Ruby version—there! That’s JRuby 9.4.2.0.
00:20:17.960
And if we run now, the client loads up the actuators register.
00:20:43.720
With this, we can't just use up and down arrows like we did before. If I press some keys, we get a hit to see one there. If I use J and K keys to move up and down, we get the other side! Whoa! JRuby wins!
00:21:42.740
But there was a client on a laptop, not exactly a mobile device that we were going for. That one’s out. We heard none of that! We heard about another option, though—Roberto!
00:22:12.340
That’s right! It was recommended to us at Rubicon in Thailand last year, and we were so excited to try it out! But when we went to the website... it was down! Ouch!
00:22:41.800
That didn’t stop us, though! We reached out to Charles Nutter, one of the contributors of Ruboto, and soon enough, the site was back up and running! We were all set to go, but when we tried to run Ruboto, we ran into incompatibility issues with the latest Android SDK.
00:23:09.700
It felt like an abandoned project since it hadn’t been worked on since 2019. But we kept looking. We scoured through conference videos and found some about Dragon Ruby and RubyMotion.
00:23:34.060
RubyMotion is a framework to build cross-platform apps for various UI environments like iOS, Android, and OS X in Ruby. It looked promising, and after a quick download, agreeing to some Android setup, and updating some Motion repo templates, we could finally create an Android project!
00:24:01.300
For running the project, it failed. We spent time chasing down versions for compatibility with ARM architectures on our MacBook Pro laptops, but to no avail.
00:24:29.520
Also, we believe RubyMotion is built on MRuby. Nothing against RubyMotion, but we needed our trifecta of CRuby, MRuby, and JRuby. RubyMotion just was not going to cut it.
00:24:56.820
So it was back to the drawing board. We looked in the App Store and found the iSH terminal app on mobile.
00:25:22.360
And sure enough, it successfully installed Ruby. That’s CRuby running its version command, displaying 2.7.8.
00:25:53.360
It was time to bring in JRuby. We successfully installed the OpenJDK and JRuby, although it took a while for the download and setup to complete. It was promising! That is, until we ran it, and even with 'jruby -v', we got a segmentation fault.
00:26:24.740
But we were desperate! So could the iSH emulator on an iPhone at least run our client card using CRuby? Let’s give that a try.
00:26:49.820
I think I go across to my iPhone, and if we open up iSH and connect to the Kickboxer LAN...
00:27:15.460
return... oh, that’s perfect control! We’re going to look for the CD to the last place I went...
00:27:37.140
So, up Arrow, up Arrow, run! This is an emulator running inside of iOS. It's waiting for actuators!
00:28:01.640
Problem finding Kickboxer LAN. This is great! I am not on the right network, am I? Let’s just give this a quick set...
00:28:20.920
So, let’s put some applause in there.
00:28:55.700
Right! Now if I go back to the iSH and run it again, hopefully now it’s connected, it’s waiting for these clients.
00:29:22.600
Press enter! Something flashing? No? That’s cool, they’re on! And if I go up, oh that’s right I have to enter, so pressing enter, there we go.
00:30:32.760
Do you want to go back to the presentation?
00:30:45.900
Oh yeah! So many things! We were on the right path. But is it JRuby? No! It's not!
00:31:08.640
It took us a while, searching in the App Store, but eventually, we found this—Rubiest!
00:31:37.500
Rubiest is a Ruby scripting platform that can run and automate Ruby code. So the first thing we tried was to require the MQTT library, and no method error! This feels like a bit of a non-starter.
00:31:58.900
Looking at the documentation, we see that there are Rubiest-specific methods and MRuby-specific methods. MRuby does not implement 'require', and Rubiest is clearly built on top of MRuby.
00:32:32.000
We were getting a little bit desperate at this point, so even though it was MRuby, how far was this thing going to take us?
00:33:09.000
Reading more, we did find out you could create widgets on the home screen, add Siri actions, and create automated shortcuts triggered by various events on the phone.
00:33:36.300
So, let's try this out. Hey Siri, run 'Hit Selena'.
00:34:10.900
Obviously, we didn’t get that to work, but it was a good try!
00:34:30.130
Writing some code in the editor was actually quite nice to use, especially on long flights to and from Australia and various conferences.
00:34:56.010
Very quickly, we found we could fetch a URL, parse some JSON, and design a simple UI. But although we could read and write TCP sockets, it was still a long way from calling MQTT.
00:35:22.520
Still, after running the code and agreeing to allow a network connection, we got a preview of the widget we could add to our home screen.
00:35:49.120
Assuming it all works well, sometimes you get a syntax error. But let's do a demo! So, if I scroll to the left, we see a Kickboxer Rubiest widget!
00:36:05.940
But it's just a widget! It only gets called once on render, and in this case, it can't have any interactions.
00:36:31.920
At that stage, there was no point in trying to build an interactive client with something that was just a widget.
00:36:51.480
And you know what? At the end of it all, it still wasn’t JRuby! We are clearly suckers for punishment, though!
00:37:12.000
So we looked for yet another option to get JRuby running. Yep, we finally made the switch to Android!
00:37:50.960
Like, I literally went out and bought a new Android phone at this point.
00:38:02.960
We thought if we could use the terminal on iPhone, surely we could do that on Android and get a better result.
00:38:24.320
We looked around on the app store, and there was a terminal app. Looking around, we found Termux—an Android terminal emulator and Linux environment app!
00:38:54.460
Another terminal app for your mobile phone, and it has running versions of CRuby, JRuby, and even MRuby! This is looking very promising!
00:39:11.460
Sure enough, it even ran our client! This is plain old CRuby, and this is JRuby! We’ve got our trifecta in Ruby on the ESP32: no CRuby, because we all know that works perfectly fine.
00:39:42.340
And we didn’t need it anyway! And JRuby on the mobile client! Whoa! Yes!
00:40:16.320
But even though it’s JRuby running on a mobile client, it’s still a terminal app—not really the touchscreen button style app we were hoping for.
00:40:36.940
As good as Termux is for running Ruby and JRuby, this isn’t quite right.
00:41:05.760
On to the next idea, by now things were getting really desperate.
00:41:26.240
If we couldn't find a way of running JRuby on an existing device, we thought maybe we’d need to build our own device!
00:41:52.040
We knew that the Raspberry Pi runs Java, so if we took a battery pack, taped on a Raspberry Pi with a Wi-Fi dongle, and attached a screen...
00:42:20.280
This is sounding like a viable plan! But making our own mobile device just to get JRuby running? I think that's going too far!
00:42:43.580
So we went back to thinking about how we could use Ruboto and Arduino together to create a client that could interact with MQTT. We knew it was a long shot, but we were determined to try!
00:43:14.960
So a few weeks ago, we were at RailsConf in Atlanta. There was a talk about JRuby to see if we could get some help moving forward with Ruboto.
00:43:46.700
I’m pretty sure Charles was stringing us along. He finally revealed some secrets we needed to install some pre-compiled APKs for Ruboto Core and Ruboto IRB, built back in 2015!
00:44:12.640
We got Ruboto IRB running with 'Hello World' and a basic UI. We actually got an Android project running with some of our own JRuby code!
00:44:38.200
That was on the train three days ago on our way rolling into Matsumoto. I don't think we have any time for more half-assed demos today.
00:45:04.240
Well, we did get a little bit of time at beer o'clock yesterday!
00:45:22.480
That’s right! Nothing like some BDD—Beer-Driven Development!
00:45:29.240
Charlie helped us debug a few permission issues and threading issues when using Android with JRuby.
00:45:54.820
Here he is! You can see him pressing the button on the app we wrote together, and you can see the blue light flashing. Success!
00:46:22.840
An Android app running JRuby, talking to a server and an actuator running the MRuby!
00:46:46.300
But we promised a kickboxing robot live on stage!
00:47:00.700
All right, I’ve got one more recording here.
00:47:41.960
So while we're setting up, I’m just going to show you that we do, in fact, have an app here, JRuby—it’s starting.
00:49:26.040
Look at that! Okay, some pool noodles on that robot!
00:49:41.100
If I press 'Kickboxer,' we're hoping for two actuators!
00:50:10.300
All right! We have one and two! I'm going to move that across and get Selena in position. Are you ready?
00:50:32.860
Are you ready? Alright! Oh, come on! You gotta duck!
00:51:03.500
It's slow!
00:51:27.440
Oh!
00:51:54.200
Alright, I think we got the live robot on stage!
00:52:48.640
Alright, so let’s recap what we’ve achieved so far.
00:53:01.760
We’ve successfully built the actuator using MRuby and it's connected to our MQTT messaging service.
00:53:29.540
We did manage to control it from a mobile client. We also did run various parts of Ruby on a whole lot of different platforms.
00:53:48.420
We ran some basic scripts on iSH, a terminal on an iPhone. We ran some Ruby scripts on Rubiest, a Ruby platform on iPhone to build out widgets, Siri commands, and shortcuts.
00:54:08.960
We ran both CRuby and JRuby on the Android terminal, Termux.
00:54:26.280
But there were a few things that didn’t work out.
00:54:41.220
Like actually managing to run Ruboto against the current Android SDK... Oh, that’s what we changed this morning because we got it running on the Android SDK!
00:54:59.850
Nothing like bedroom development! So the only thing that actually didn't work out...
00:55:19.760
No, nothing! Everything worked out!
00:55:34.650
I think I don’t think these actuators are running everything in MRuby just yet!
00:55:45.740
So there’s probably a little bit of work there to make MRuby work a little bit better.
00:56:03.020
Plus, as we said, that deployment pipeline we used was complicated!
00:56:22.730
Although, to be honest, we didn’t really give Dragon Ruby a fair go. There does seem to be a lot going on in the Dragon Ruby Game Toolkit, though!
00:56:52.020
Maybe we should just write a game next time! Speaking of next time, how can we top this for RubyKaigi 2024?
00:57:07.560
Well, we could always take our MRuby project to another Ruby level!
00:57:25.620
Being learning algorithms to assist the system to personalize the training experience for different users!
00:57:45.040
Or we could do what we set out to do, and figure out how to rewrite all that C code in Ruby, as we saw Ruby was way more accessible for writing and developing!
00:58:03.920
Our friends at Ruboto need some help! Maybe someone in the audience could help out with getting that project compatible with the Android SDK!
00:58:25.040
And it sounds like there's a lot going on in the MRuby and PicoRuby communities. It would be cool to get a better understanding of how to use MRuby for IoT development!
00:59:09.960
All in all, we're really excited about the potential of this project and can't wait to see where it goes next!
00:59:41.120
That's right! We hope we’ve inspired some of you to explore the possibilities of using Ruby and IoT projects.
00:59:58.800
From the B2B fresh food ordering platform Fresh, this is Selena Small!
01:00:16.600
[Laughs] And from the payments API, Zepto, I'm Michael Malevsky. Thank you very much!
01:00:53.840
Come back! You do have to stand back, I know! I don't want to be too big.
01:01:05.600
Oh, okay. All right, now going crazy! Oh, hang on... Thank you!