WEBVTT

00:00:01.490 --> 00:00:05.950
<v Matthias>It's Rust in Production, a podcast about companies who use Rust to shape the

00:00:05.950 --> 00:00:06.850
<v Matthias>future of infrastructure.

00:00:07.190 --> 00:00:11.530
<v Matthias>My name is Matthias Endler from corrode, and today we talk to Sebastian Scholz

00:00:11.530 --> 00:00:16.170
<v Matthias>from Gama Space about controlling solar sails and satellites with Rust.

00:00:19.010 --> 00:00:23.050
<v Matthias>Sebastian, thanks very much for taking the time for the interview today.

00:00:23.230 --> 00:00:25.670
<v Matthias>Can you say a few words about yourself and about Gama?

00:00:26.170 --> 00:00:30.510
<v Sebastian>Yes, thank you very much for having me, Matthias. I'm very excited to be here.

00:00:30.710 --> 00:00:36.550
<v Sebastian>My name is Sebastian Scholz, and I'm an electronics and embedded system engineer at Gama Space.

00:00:36.890 --> 00:00:42.790
<v Sebastian>We are based in Paris, and I've been with Gama Space since January 2023.

00:00:44.030 --> 00:00:50.330
<v Sebastian>Our mission, our Gama Space's mission, is to develop and provide a propulsion

00:00:50.330 --> 00:00:53.030
<v Sebastian>technology called solar sails in space.

00:00:53.870 --> 00:01:00.990
<v Sebastian>And to do that, we are using rust in various places. And that's what I'm here to talk about.

00:01:01.470 --> 00:01:08.130
<v Matthias>Now, not everyone might be familiar what a solar sail is. Can you describe the principle behind it?

00:01:08.510 --> 00:01:12.070
<v Sebastian>Yes. So the concept is actually rather simple.

00:01:12.570 --> 00:01:16.790
<v Sebastian>You know, when you have a sail on a boat, you have the wind blowing into it.

00:01:17.050 --> 00:01:22.630
<v Sebastian>In space, you don't have that, but you have the sun. And the photons of the

00:01:22.630 --> 00:01:26.110
<v Sebastian>sun provide some amount of pressure on a sail.

00:01:26.250 --> 00:01:31.610
<v Sebastian>So if you have reflective space, the reflections of the photon give you an impulse

00:01:31.610 --> 00:01:34.130
<v Sebastian>and so provide momentum to your sail.

00:01:34.270 --> 00:01:41.270
<v Sebastian>So basically, it's a way of moving in space, but without fuel and just relying on the sun.

00:01:41.610 --> 00:01:41.950
<v Matthias>Wow.

00:01:43.890 --> 00:01:45.830
<v Matthias>Basically, free propulsion.

00:01:46.490 --> 00:01:50.270
<v Sebastian>Basically, free propulsion. That's exactly it. The main advantage of it,

00:01:50.410 --> 00:01:54.030
<v Sebastian>of combustion propulsion, is that you don't need to bring your fuel with you.

00:01:54.430 --> 00:01:58.670
<v Sebastian>So, as you might know, it's still kind of hard to get mass into space.

00:01:58.670 --> 00:02:06.230
<v Sebastian>So, by saving all of this potential fuel mass, it's going to be easier and cheaper to go into space.

00:02:06.450 --> 00:02:09.390
<v Matthias>And the trade-off is speed, I'm assuming, right?

00:02:09.390 --> 00:02:15.010
<v Sebastian>Yes, of course, there are some downsides compared to a normal combustion engine.

00:02:15.370 --> 00:02:18.730
<v Sebastian>The impulse, the specific impulse that you get is rather low.

00:02:18.850 --> 00:02:23.850
<v Sebastian>So that means the acceleration is extremely low, actually, in the area of a

00:02:23.850 --> 00:02:27.750
<v Sebastian>few newtons versus kilonewtons that you get from normal propulsion.

00:02:27.950 --> 00:02:31.390
<v Sebastian>So that means you have to plan your trajectories accordingly.

00:02:31.950 --> 00:02:36.910
<v Sebastian>But, I mean, the benefit is that this propulsion is infinite compared to the

00:02:36.910 --> 00:02:40.190
<v Sebastian>fuel, because at some point fuel runs out. But the sun, it's going to take a

00:02:40.190 --> 00:02:41.510
<v Sebastian>very long time for it to run out.

00:02:42.110 --> 00:02:43.790
<v Matthias>Unless you're too far away from the sun.

00:02:44.570 --> 00:02:48.210
<v Sebastian>Yeah, but even if you're too far away from the sun, you still get some amount

00:02:48.210 --> 00:02:51.130
<v Sebastian>of propulsion. I mean, it's not like you're on an empty tank.

00:02:51.710 --> 00:02:57.050
<v Sebastian>You still have some amount of movability even if the sun is very low.

00:02:57.350 --> 00:03:03.170
<v Sebastian>But if you're on the outside of the solar system, you're going to have to move

00:03:03.170 --> 00:03:05.350
<v Sebastian>a bit slower. Yes, that's absolutely true.

00:03:05.990 --> 00:03:10.650
<v Matthias>It's not a physics podcast, but at the same time, I'm always curious about space.

00:03:10.810 --> 00:03:13.930
<v Matthias>It's a thing that's fascinated me since I was a child.

00:03:14.130 --> 00:03:21.570
<v Matthias>And a lot of people, they requested an episode with you and with the project

00:03:21.570 --> 00:03:25.890
<v Matthias>that you do, which we're here to talk about, because you also happen to use Rust.

00:03:26.490 --> 00:03:29.710
<v Sebastian>Yes, quite extensively, as a matter of fact.

00:03:30.090 --> 00:03:35.990
<v Sebastian>So for the solar sails, we have launched in January 2023.

00:03:36.010 --> 00:03:39.930
<v Sebastian>So right around the time when I joined the company, we've launched a satellite,

00:03:40.230 --> 00:03:44.510
<v Sebastian>a demonstration mission for this technology, the solar sails.

00:03:44.770 --> 00:03:48.570
<v Sebastian>And the onboard data handling system, our part of the satellite,

00:03:48.790 --> 00:03:51.290
<v Sebastian>is more or less completely written in rust.

00:03:51.290 --> 00:03:58.290
<v Sebastian>So we have a few sealers underneath the hood, but the main code and all of the

00:03:58.290 --> 00:04:01.430
<v Sebastian>supporting test equipment was written using Rust.

00:04:02.510 --> 00:04:08.330
<v Matthias>Now, isn't it extremely risky to use Rust for such a mission?

00:04:08.330 --> 00:04:10.550
<v Matthias>You don't really have that many tries anyway.

00:04:10.570 --> 00:04:13.310
<v Matthias>It's not like redeploying a backend or so.

00:04:13.770 --> 00:04:19.270
<v Sebastian>Yes, there's one of the great dangers if you develop something for space.

00:04:19.270 --> 00:04:22.290
<v Sebastian>You get one shot with your

00:04:22.290 --> 00:04:24.990
<v Sebastian>satellites and if you mess it up it's not like you

00:04:24.990 --> 00:04:29.030
<v Sebastian>could just go up and try to reboot it you know you you

00:04:29.030 --> 00:04:31.790
<v Sebastian>really have only one shot but the mindset that

00:04:31.790 --> 00:04:37.510
<v Sebastian>we have at Gama is the mindset of the new space companies so we try to move

00:04:37.510 --> 00:04:45.310
<v Sebastian>fast and fail fail fast so we try a bunch of new things and if we do fail it's

00:04:45.310 --> 00:04:50.010
<v Sebastian>unfortunate of course but it's not a big deal That's kind of how we do learn.

00:04:50.850 --> 00:04:55.610
<v Sebastian>And so what we wanted to do with this mission, it's a demonstration mission.

00:04:55.730 --> 00:04:59.970
<v Sebastian>So we wanted to demonstrate our technology, but we also wanted to try out new things.

00:05:00.290 --> 00:05:06.330
<v Sebastian>And so using Rust as the main driver for our onboard data handling system was

00:05:06.330 --> 00:05:11.590
<v Sebastian>one of these decisions that we wanted to try out to see if it's going to be

00:05:11.590 --> 00:05:13.010
<v Sebastian>usable for the future as well.

00:05:13.480 --> 00:05:19.120
<v Matthias>And before we talk about the onboard data handling system, what do you define

00:05:19.120 --> 00:05:24.320
<v Matthias>as new space and what are maybe other companies in that realm?

00:05:25.080 --> 00:05:31.600
<v Sebastian>Yeah, so the main one that is probably known to everyone is SpaceX in that regard.

00:05:31.600 --> 00:05:37.700
<v Sebastian>And you can definitely see in the way they work that they like to fail fast as well.

00:05:38.220 --> 00:05:42.960
<v Sebastian>I mean, just look at the Starship launches. The development of this kind of

00:05:42.960 --> 00:05:48.780
<v Sebastian>rocket is extremely difficult, but they're doing it very fast and they're failing very fast as well.

00:05:48.880 --> 00:05:52.020
<v Sebastian>I mean, many of these launches end with spectacular explosions.

00:05:52.400 --> 00:05:58.460
<v Sebastian>And so the mentality is, yeah, OK, we're going to have to spend a lot of resources,

00:05:58.460 --> 00:06:01.340
<v Sebastian>but we're going to learn a lot of it as well.

00:06:02.330 --> 00:06:05.130
<v Sebastian>You're doing the failure so yeah that's

00:06:05.130 --> 00:06:08.050
<v Sebastian>that's just one way of moving forward versus in the past

00:06:08.050 --> 00:06:10.910
<v Sebastian>the kind of old space which

00:06:10.910 --> 00:06:17.870
<v Sebastian>is the big entities like nasa they want to do it once and want to do it correctly

00:06:17.870 --> 00:06:22.790
<v Sebastian>and i mean this mindset is also very important if you're doing like deep space

00:06:22.790 --> 00:06:26.810
<v Sebastian>missions as well where it takes a really long time to get to places for example

00:06:26.810 --> 00:06:28.990
<v Sebastian>i mean as well if you want to go to Mars.

00:06:29.670 --> 00:06:35.630
<v Sebastian>You kind of get one shot and if you don't do it correctly, you're going to have

00:06:35.630 --> 00:06:38.290
<v Sebastian>to wait a couple 10 or more years to get back.

00:06:38.470 --> 00:06:44.770
<v Matthias>Okay, it's a test mission and yet it is foundational software that you're writing

00:06:44.770 --> 00:06:51.390
<v Matthias>because you might as well just use some of the more established or some of the

00:06:51.390 --> 00:06:53.390
<v Matthias>more common languages like C,

00:06:53.550 --> 00:07:00.310
<v Matthias>C++ or maybe even ADA for the test mission for Gama Alpha but you chose rust why.

00:07:00.310 --> 00:07:03.970
<v Sebastian>So this mainly boils down to our

00:07:03.970 --> 00:07:06.950
<v Sebastian>software engineer at the time so this was

00:07:06.950 --> 00:07:12.510
<v Sebastian>before i started working at the company i i didn't mention but the Gama Space

00:07:12.510 --> 00:07:19.770
<v Sebastian>itself is only about five years old now so it was founded in the 2020s and we

00:07:19.770 --> 00:07:26.090
<v Sebastian>well We kind of move relatively fast and the team only grows relatively so.

00:07:26.210 --> 00:07:28.970
<v Sebastian>So right now we are, I think, 21 people in the company.

00:07:29.110 --> 00:07:32.530
<v Sebastian>And at that point, when we launched Alpha, it was more like 12.

00:07:33.630 --> 00:07:38.710
<v Sebastian>And most of our team is actually in mechanics because as you can imagine,

00:07:38.910 --> 00:07:44.010
<v Sebastian>I mean, the folding and creation of the sale is its own topic.

00:07:44.470 --> 00:07:49.090
<v Sebastian>It's one of the main things that we do. And so we only had one team

00:07:49.510 --> 00:07:52.350
<v Sebastian>electronics and embedded systems engineer the one that was

00:07:52.350 --> 00:07:56.310
<v Sebastian>responsible for the creation of of

00:07:56.310 --> 00:07:59.450
<v Sebastian>the on-board data handling system at the time which is

00:07:59.450 --> 00:08:05.350
<v Sebastian>a colleague of mine called Chris and his background was mainly in c plus plus

00:08:05.350 --> 00:08:13.410
<v Sebastian>and so he decided but he he knew that c plus plus was not well suited for well

00:08:13.410 --> 00:08:17.970
<v Sebastian>i mean it was difficult to use to get a reliable piece of software for the space environments.

00:08:18.190 --> 00:08:23.570
<v Sebastian>And so when he looked into options and other kind of languages to use,

00:08:24.370 --> 00:08:29.630
<v Sebastian>he decided that Rust would be a perfect fit for our case. He had a little bit

00:08:29.630 --> 00:08:31.410
<v Sebastian>of prior experiences in it as well.

00:08:31.710 --> 00:08:34.350
<v Sebastian>And so that's why we didn't choose Ada, for example.

00:08:35.510 --> 00:08:39.570
<v Matthias>And how did he evaluate Rust? I know that you were not there,

00:08:39.730 --> 00:08:43.930
<v Matthias>but maybe you talked to them about it. Why did they choose it?

00:08:43.930 --> 00:08:51.350
<v Sebastian>Yes. So basically, he did a trade-off of Rust versus other languages.

00:08:51.930 --> 00:08:57.590
<v Sebastian>And I mean, it came out clearly on top. The memory safety, just eradicating

00:08:57.590 --> 00:09:03.710
<v Sebastian>a whole bunch of errors that you can have with C and C++ is really critical

00:09:03.710 --> 00:09:05.410
<v Sebastian>for space applications.

00:09:05.410 --> 00:09:11.190
<v Sebastian>It's these kind of avoidable errors that can be caught before you deploy your

00:09:11.190 --> 00:09:14.710
<v Sebastian>code, that can just be denied by the compiler.

00:09:15.210 --> 00:09:20.950
<v Sebastian>And in general, the help that the compiler gives you compared to other languages

00:09:20.950 --> 00:09:26.790
<v Sebastian>in writing safe and good code, this I think was the main driver.

00:09:26.790 --> 00:09:31.810
<v Sebastian>And, of course, the ability to still go into the embedded systems level,

00:09:32.010 --> 00:09:35.490
<v Sebastian>still be real-time and be reliable.

00:09:37.510 --> 00:09:41.110
<v Matthias>How can I imagine day-to-day at Gama?

00:09:41.170 --> 00:09:48.970
<v Matthias>Do you use any special software that us normal, let's say, earthly Rust developers don't use?

00:09:49.090 --> 00:09:54.270
<v Matthias>Or would you say, no, it's mostly the same components, it's mostly the same

00:09:54.270 --> 00:10:00.150
<v Matthias>code structure, it's the same CI/CD platform like any other project?

00:10:00.690 --> 00:10:05.290
<v Sebastian>Yeah, actually, it's very, very similar. So in a bunch of companies,

00:10:05.290 --> 00:10:09.490
<v Sebastian>you would find setups with GitLab, for example, and so do we have it.

00:10:09.850 --> 00:10:16.310
<v Sebastian>We use a lot of crates that are just out there for many people to use,

00:10:16.710 --> 00:10:22.670
<v Sebastian>like ZeroCopy, for example, and other things, probe-rs for our debugging environment.

00:10:24.170 --> 00:10:29.170
<v Sebastian>It's a little bit more specific because we work with hardware.

00:10:29.590 --> 00:10:35.150
<v Sebastian>So in many software companies, you have your code, you have unit tests,

00:10:35.290 --> 00:10:39.270
<v Sebastian>you have integration tests that you run on your CI, and that's that.

00:10:39.450 --> 00:10:41.590
<v Sebastian>We have to interface with actual real hardware.

00:10:42.070 --> 00:10:49.630
<v Sebastian>And so maybe one of the key differences is that we have a flat-sat for the Gama Alpha

00:10:49.630 --> 00:10:51.930
<v Sebastian>product, so for theGama Alpha satellite. A

00:10:52.910 --> 00:10:57.970
<v Sebastian>flat-sat, I should say, is basically the electronics of the satellite unwrapped,

00:10:58.150 --> 00:11:02.430
<v Sebastian>laid out on a flat on a table, hence the name flat set.

00:11:02.430 --> 00:11:07.650
<v Sebastian>And it's a one-to-one, pretty much a one-to-one copy of the actual hardware

00:11:07.650 --> 00:11:12.670
<v Sebastian>of the satellite and we integrated it in our CI so that our tests,

00:11:12.970 --> 00:11:18.190
<v Sebastian>we have mainly integration tests and they run on the actual hardware and then

00:11:18.190 --> 00:11:25.210
<v Sebastian>we have probes attached to look at the actual output of the system and make

00:11:25.210 --> 00:11:26.210
<v Sebastian>sure that everything is all right.

00:11:26.770 --> 00:11:31.590
<v Matthias>It's kind of cool that you use probe-rs especially because,

00:11:33.330 --> 00:11:39.170
<v Matthias>All of the embedded, or I call it embedded, but like all of the low-level projects

00:11:39.170 --> 00:11:42.350
<v Matthias>that I know of use it to some extent.

00:11:42.850 --> 00:11:46.450
<v Matthias>Was it a natural choice for you? Did you evaluate anything else?

00:11:46.630 --> 00:11:51.030
<v Matthias>Is there even anything else in that space? Or is probe-rs the de facto standard now?

00:11:51.850 --> 00:11:58.490
<v Sebastian>Yeah, it took us a while to get all of these systems up and running.

00:11:58.590 --> 00:12:02.650
<v Sebastian>And in the process of doing so, we did evaluate multiple things.

00:12:02.650 --> 00:12:06.850
<v Sebastian>But there was not a lot of choice for this sort of thing.

00:12:07.030 --> 00:12:13.670
<v Sebastian>We could have also just used regular C debuggers, as in just start a different

00:12:13.670 --> 00:12:16.130
<v Sebastian>process with the debugger and then interface with that.

00:12:16.310 --> 00:12:20.390
<v Sebastian>That was one of the other options that we looked at.

00:12:20.930 --> 00:12:23.870
<v Sebastian>I mean, that would basically have been the normal C approach,

00:12:24.070 --> 00:12:28.490
<v Sebastian>you know, like just use a GDB, for example, as a debugger.

00:12:29.950 --> 00:12:35.130
<v Sebastian>But the benefit of probe-rs was that, of course, it was written in Rust,

00:12:35.310 --> 00:12:42.770
<v Sebastian>and it allowed for a lot more fine-grained control of what we wanted to do with our integration tests.

00:12:42.770 --> 00:12:47.510
<v Sebastian>For example, we have a system to compile,

00:12:47.830 --> 00:12:54.070
<v Sebastian>test Rust binaries, and then upload them via probe-rs onto the actual hardware,

00:12:54.250 --> 00:12:58.190
<v Sebastian>and then look at the output and look for certain signals to make sure that the

00:12:58.190 --> 00:13:00.050
<v Sebastian>test that this binary represents passes.

00:13:00.530 --> 00:13:05.550
<v Sebastian>So that was very easy to do in Rust and using probe-rs.

00:13:06.030 --> 00:13:11.630
<v Matthias>And how does that system look like? How does it work? What's the end-to-end development flow? So,

00:13:12.900 --> 00:13:16.700
<v Matthias>So I'm guessing you develop code in your IDE. I'm not sure which IDE you use.

00:13:16.980 --> 00:13:25.740
<v Sebastian>Yeah, so we use VS Code. And so if we want to develop a new feature or work on some code,

00:13:26.040 --> 00:13:30.500
<v Sebastian>the typical workflow would be, so you write your code, you push it onto a new

00:13:30.500 --> 00:13:32.920
<v Sebastian>branch, and as soon as you push,

00:13:33.380 --> 00:13:36.940
<v Sebastian>our CI starts, and it reserves a slot on the flat side.

00:13:37.180 --> 00:13:40.340
<v Sebastian>The interesting thing is that we also use the flat side for manual debugging.

00:13:40.340 --> 00:13:44.340
<v Sebastian>So we have kind of a little bit of a system where you can reserve a slot on

00:13:44.340 --> 00:13:47.060
<v Sebastian>the flat set. During that time, the CI can't run and has to wait.

00:13:47.380 --> 00:13:50.780
<v Sebastian>But if the CI is running, you have to wait for a bit until it's finished.

00:13:51.240 --> 00:13:56.360
<v Sebastian>And so we kind of have a little server, which unsurprisingly is also written in Rust.

00:13:57.900 --> 00:14:00.980
<v Sebastian>Yes, that kind of manages the access to the flat set.

00:14:01.660 --> 00:14:02.780
<v Matthias>And you wrote that yourself?

00:14:03.120 --> 00:14:05.960
<v Sebastian>Yeah, we wrote it ourselves. I think, oh, it's been a while,

00:14:05.960 --> 00:14:10.900
<v Sebastian>but I think it uses Hyper as a web server.

00:14:11.080 --> 00:14:13.200
<v Sebastian>I think it's called Hyper. Yeah.

00:14:14.240 --> 00:14:20.200
<v Sebastian>And basically, it manages access to it. At that time, so it has a web interface,

00:14:20.200 --> 00:14:24.840
<v Sebastian>and at that time, we wanted to kind of get fancy, and I have a little bit of

00:14:24.840 --> 00:14:27.340
<v Sebastian>a background in Flutter development as well.

00:14:27.520 --> 00:14:34.460
<v Sebastian>So the web interface is based on Flutter, but the actual logic and the serving of the files is in Rust.

00:14:34.840 --> 00:14:37.820
<v Matthias>Oh, wow. that's a

00:14:37.820 --> 00:14:41.660
<v Matthias>really cool project in and of itself because because i

00:14:41.660 --> 00:14:46.740
<v Matthias>really wondered how would you how would you test your hardware components you

00:14:46.740 --> 00:14:51.540
<v Matthias>kind of want to abstract that away you don't want to unplug and plug it back

00:14:51.540 --> 00:14:55.820
<v Matthias>in again you kind of want to have a system for that and i'm assuming that there's

00:14:55.820 --> 00:15:00.500
<v Matthias>not much on the market especially for flat sets like this it's probably a,

00:15:01.180 --> 00:15:04.180
<v Matthias>Still an embedded setup, just like any other embedded setups.

00:15:04.360 --> 00:15:10.240
<v Matthias>But the moment you go into the details here, you will find that you probably

00:15:10.240 --> 00:15:11.400
<v Matthias>need a custom solution, right?

00:15:12.040 --> 00:15:16.440
<v Sebastian>Exactly. So this is one of the unfortunate truth. If you do develop your own

00:15:16.440 --> 00:15:20.240
<v Sebastian>system, there's no one solution fits all kind of a thing.

00:15:20.620 --> 00:15:25.480
<v Sebastian>So we did try to find generic solutions for embedded testing.

00:15:25.760 --> 00:15:29.060
<v Sebastian>And I don't know how it looks right now, but a couple of years ago,

00:15:29.280 --> 00:15:33.780
<v Sebastian>two and a half years ago, So there wasn't really a lot that helped you write

00:15:33.780 --> 00:15:37.320
<v Sebastian>actual tests for the embedded target and run them.

00:15:37.780 --> 00:15:42.280
<v Sebastian>So yes, this solution of the integration tests and the test suite itself is

00:15:42.280 --> 00:15:45.120
<v Sebastian>also a custom solution that we developed in Rust as well.

00:15:45.600 --> 00:15:50.280
<v Sebastian>So the whole integration test suite is also written in Rust and developed in-house.

00:15:51.260 --> 00:15:55.360
<v Matthias>But the integration tests are still in a tests folder, just like you would expect

00:15:55.360 --> 00:15:57.060
<v Matthias>from any normal Rust project, right?

00:15:57.300 --> 00:16:00.320
<v Sebastian>Yes, pretty much. so basically it's a

00:16:00.320 --> 00:16:05.920
<v Sebastian>binary that has all of the tests in it and then we just upload this binary to

00:16:05.920 --> 00:16:11.000
<v Sebastian>the hardware and then let it run and we look at the output via communication

00:16:11.000 --> 00:16:17.520
<v Sebastian>protocol I think for that we use just UART very common low-level communication protocol.

00:16:18.860 --> 00:16:23.740
<v Matthias>Now earlier you mentioned correctness in a different context but I think it

00:16:23.740 --> 00:16:32.500
<v Matthias>fits in here as well because couldn't you test a lot of the logic with unit tests?

00:16:33.320 --> 00:16:39.960
<v Matthias>Or is it so that you kind of want to always test the inputs and outputs as well

00:16:39.960 --> 00:16:42.440
<v Matthias>because it's kind of a monolithic service?

00:16:44.280 --> 00:16:52.200
<v Sebastian>Yeah, we have some unit tests and for smaller functionalities we do use those to test.

00:16:53.960 --> 00:16:57.560
<v Sebastian>The theme that we have in our code is we have one,

00:16:58.680 --> 00:17:01.520
<v Sebastian>big project but it's it's built

00:17:01.520 --> 00:17:04.520
<v Sebastian>up in smaller crates so the big kind of onboard data

00:17:04.520 --> 00:17:07.300
<v Sebastian>handling system software uses a lot of smaller crates

00:17:07.300 --> 00:17:10.100
<v Sebastian>that we also develop and the smaller crates they

00:17:10.100 --> 00:17:12.960
<v Sebastian>have unit tests for their functionality but for

00:17:12.960 --> 00:17:17.120
<v Sebastian>the big onboard data handling system it's harder

00:17:17.120 --> 00:17:22.640
<v Sebastian>to test these things because they're very much hardware specific so for example

00:17:22.640 --> 00:17:28.880
<v Sebastian>if i want to test that our persistence works so we are able to store data in

00:17:28.880 --> 00:17:32.620
<v Sebastian>some sort of flash memory i can't just write a unit test for it because i need

00:17:32.620 --> 00:17:36.240
<v Sebastian>the actual hardware i sure i could try to emulate it somehow,

00:17:37.240 --> 00:17:40.860
<v Sebastian>but that's a bunch of extra work and i'm not guaranteed that it is going to

00:17:40.860 --> 00:17:46.820
<v Sebastian>actually work on the hardware itself so in an embedded environment you you kind of can't,

00:17:47.490 --> 00:17:51.750
<v Sebastian>avoid doing integration tests because you need to test on the hardware so you're

00:17:51.750 --> 00:17:54.470
<v Sebastian>just going to test the whole system as a whole yeah.

00:17:54.470 --> 00:17:58.250
<v Matthias>Well when you say that you store files on

00:17:58.250 --> 00:18:04.870
<v Matthias>flash in a normal scenario it wouldn't be a problem if the flash storage fails

00:18:04.870 --> 00:18:10.090
<v Matthias>you can't just you know fix it because it's maybe right next to you but it's

00:18:10.090 --> 00:18:16.430
<v Matthias>harder to do in space do you have any failover for that sort of hardware failure?

00:18:16.650 --> 00:18:18.210
<v Matthias>And if so, how do you test that?

00:18:19.270 --> 00:18:25.390
<v Sebastian>Yeah. So in fact, all of our flash memory, first of all, it's a very specific

00:18:25.390 --> 00:18:29.570
<v Sebastian>chip usually that has some built-in error detection and correction.

00:18:29.910 --> 00:18:33.290
<v Sebastian>So on a hardware level, we are protected against it.

00:18:33.390 --> 00:18:39.110
<v Sebastian>But on top of that, for specific parts of code that is stored on this flash,

00:18:39.250 --> 00:18:41.410
<v Sebastian>because that's the important thing.

00:18:41.830 --> 00:18:45.690
<v Sebastian>Code needs to be stored somewhere. And so if that code gets corrupted,

00:18:46.070 --> 00:18:47.710
<v Sebastian>you're going to be in big trouble.

00:18:47.930 --> 00:18:54.470
<v Sebastian>So one of the steps that we do in our bootloaders is that we check this code for errors.

00:18:57.030 --> 00:19:00.850
<v Sebastian>For example, for bit flips. In space, you have radiation.

00:19:01.050 --> 00:19:06.790
<v Sebastian>And so just random bits in your data and your code in that instance can just

00:19:06.790 --> 00:19:09.650
<v Sebastian>randomly fit, which can mess up the entire code flow.

00:19:09.870 --> 00:19:17.670
<v Sebastian>So we have steps. We have code written to verify that the stored code that we

00:19:17.670 --> 00:19:22.710
<v Sebastian>have in our flash memory is correct and that can potentially even recover from errors.

00:19:23.010 --> 00:19:28.810
<v Sebastian>So there's something called a hemming code, which means you basically reserve

00:19:28.810 --> 00:19:33.310
<v Sebastian>some extra space for redundant bits and you can use those bits later to detect

00:19:33.310 --> 00:19:36.110
<v Sebastian>and to recover from flipped bits.

00:19:36.110 --> 00:19:42.470
<v Sebastian>And this kind of code we have integration tests that uses prop.is to manually

00:19:42.470 --> 00:19:47.390
<v Sebastian>write into the flash into memory even and to flip some bits,

00:19:48.190 --> 00:19:52.850
<v Sebastian>And then we'll let it boot, see that it handles these kind of corruptions that

00:19:52.850 --> 00:19:55.710
<v Sebastian>we introduce correctly and fixes itself, yes.

00:19:56.630 --> 00:19:58.410
<v Matthias>And that's also a custom solution?

00:19:58.970 --> 00:20:03.910
<v Sebastian>Yes. I mean, this is one of the tests that we run during our integration tests.

00:20:04.310 --> 00:20:12.050
<v Sebastian>So, yes, the integration test suite has a component that allows it to write into this flash memory.

00:20:12.150 --> 00:20:14.450
<v Sebastian>And that is developed by us, and that's a custom solution.

00:20:14.450 --> 00:20:17.150
<v Matthias>Indeed let's talk

00:20:17.150 --> 00:20:20.030
<v Matthias>a little bit about your background where you

00:20:20.030 --> 00:20:25.830
<v Matthias>came from what your other strong languages were and how you got onboarded on

00:20:25.830 --> 00:20:30.470
<v Matthias>the project and your first experiences with the code base a lot of people might

00:20:30.470 --> 00:20:38.230
<v Matthias>be curious about you know exactly this process of working for quote-unquote a space company so.

00:20:38.230 --> 00:20:44.430
<v Sebastian>During my studies when i joined I joined a lot of projects that do things in space.

00:20:44.570 --> 00:20:48.970
<v Sebastian>So for example, one of the cool things that we did back then was something called

00:20:48.970 --> 00:20:57.170
<v Sebastian>Bexus and Rexus, which is a European project for students that allow you to do some sort of project,

00:20:57.370 --> 00:21:01.610
<v Sebastian>some sort of scientific mission on a small suborbital rocket or weather balloon

00:21:01.610 --> 00:21:03.570
<v Sebastian>that they launched from Sweden.

00:21:03.930 --> 00:21:08.030
<v Sebastian>And so that's kind of where I got exposed to my first real mission

00:21:08.440 --> 00:21:11.860
<v Sebastian>Bayes mission experience using those projects

00:21:11.860 --> 00:21:14.920
<v Sebastian>and we used a bunch of different languages though

00:21:14.920 --> 00:21:18.380
<v Sebastian>mainly C and Python and I

00:21:18.380 --> 00:21:25.020
<v Sebastian>must admit before I joined Gama and in my university days I have never heard

00:21:25.020 --> 00:21:32.400
<v Sebastian>of or used Rust so I'm kind of a late joiner in that regard but after finishing

00:21:32.400 --> 00:21:38.340
<v Sebastian>my studies I joined Gama then in January 2023 and that's

00:21:38.440 --> 00:21:42.420
<v Sebastian>The point when I started to learn about Rust and when I kind of fell in love

00:21:42.420 --> 00:21:47.540
<v Sebastian>with it because of the security guarantees that it gives you.

00:21:47.740 --> 00:21:52.020
<v Sebastian>You mentioned earlier that all of the stuff that we have talked before must

00:21:52.020 --> 00:21:54.520
<v Sebastian>have been in place before. And that's actually not the case.

00:21:54.980 --> 00:21:59.860
<v Sebastian>This is one of the reasons I got onboarded because at the time it was literally

00:21:59.860 --> 00:22:03.820
<v Sebastian>just Chris responsible for the software.

00:22:03.820 --> 00:22:10.620
<v Sebastian>And so we really needed more support in the electronics and in the software

00:22:10.620 --> 00:22:12.660
<v Sebastian>department, embedded software department.

00:22:12.880 --> 00:22:18.280
<v Sebastian>And so that's where I came in. Although I couldn't directly start working on

00:22:18.280 --> 00:22:19.520
<v Sebastian>the onboard data handling system.

00:22:19.780 --> 00:22:23.920
<v Sebastian>Well, I did some small contributions here and there. But when I started,

00:22:24.240 --> 00:22:27.800
<v Sebastian>I got assigned to a kind of a side project.

00:22:28.160 --> 00:22:33.260
<v Sebastian>So you have to imagine the satellite has just launched a few days ago.

00:22:33.820 --> 00:22:38.100
<v Sebastian>I come into the company, I get used to everyone, everything,

00:22:38.360 --> 00:22:45.140
<v Sebastian>meet everyone, and then, ah, okay, we have kind of a validation of our satellite.

00:22:45.520 --> 00:22:50.200
<v Sebastian>We want to do a zero-g flight. So that is a flight where the plane.

00:22:51.370 --> 00:22:54.530
<v Sebastian>Does a parable so it goes up and

00:22:54.530 --> 00:22:57.690
<v Sebastian>then it flies in a way so that you you cancel

00:22:57.690 --> 00:23:01.170
<v Sebastian>out gravity so you for a few seconds

00:23:01.170 --> 00:23:04.350
<v Sebastian>like 30 seconds you are weightless and we

00:23:04.350 --> 00:23:07.670
<v Sebastian>wanted to use that and develop a system to have a

00:23:07.670 --> 00:23:11.310
<v Sebastian>small scale solar sail deployed and to

00:23:11.310 --> 00:23:14.130
<v Sebastian>see how it how it behaves in COG because we

00:23:14.130 --> 00:23:18.010
<v Sebastian>they had simulations at the time but there

00:23:18.010 --> 00:23:20.770
<v Sebastian>was no practical experience and so we wanted to we wanted

00:23:20.770 --> 00:23:23.550
<v Sebastian>to see if our simulations actually match what we see

00:23:23.550 --> 00:23:27.490
<v Sebastian>in real life and so i got assigned to build this

00:23:27.490 --> 00:23:32.490
<v Sebastian>specific project and the code for it and of course because we were using rust

00:23:32.490 --> 00:23:38.610
<v Sebastian>this was also done in rust so they it's kind of it was kind of a relative simple

00:23:38.610 --> 00:23:45.890
<v Sebastian>thing we just had three motors and we were controlling a a disk inside of a box and on the disk so we

00:23:46.050 --> 00:23:52.510
<v Sebastian>were able to spin the disk and then release something that released our small-scale sail.

00:23:53.910 --> 00:24:00.850
<v Sebastian>And the main part of this was just to do this control, kind of account for vibrations

00:24:00.850 --> 00:24:05.350
<v Sebastian>of the plane because those kind of disturb the data and then record the data, of course.

00:24:05.590 --> 00:24:12.070
<v Sebastian>There was a lot of data coming in because we wanted to record as much as possible from this experience.

00:24:12.190 --> 00:24:16.810
<v Sebastian>We had cameras that captured the entire thing, but we also had various sensors,

00:24:17.310 --> 00:24:20.230
<v Sebastian>accelerators, and stuff like that.

00:24:20.710 --> 00:24:23.350
<v Sebastian>So that was kind of my first...

00:24:24.890 --> 00:24:28.490
<v Sebastian>My my foot into into the company and that's

00:24:28.490 --> 00:24:31.490
<v Sebastian>kind of also still what we do today if we

00:24:31.490 --> 00:24:36.350
<v Sebastian>if somebody else joins the company they're gonna have to get used to the way

00:24:36.350 --> 00:24:40.030
<v Sebastian>we work around here they're gonna have to get used to rust potentially and so

00:24:40.030 --> 00:24:45.050
<v Sebastian>they they usually get a small project on the site where they can they can work

00:24:45.050 --> 00:24:50.930
<v Sebastian>on it's still important to us of course and then they they kind of join the main force,

00:24:51.570 --> 00:24:56.030
<v Sebastian>like that and we have a bunch of back and forth where we because you're learning

00:24:56.030 --> 00:25:06.070
<v Sebastian>the way of how to write code not only for Rust but also for space there's a bunch of things that we,

00:25:07.370 --> 00:25:15.230
<v Sebastian>how to's that we have in the company that we've gathered over the years on how

00:25:15.230 --> 00:25:21.510
<v Sebastian>to write Rust safely as possible because unfortunately, it's still possible to screw up in Rust.

00:25:24.830 --> 00:25:26.650
<v Matthias>Is it? Yes.

00:25:27.230 --> 00:25:30.070
<v Sebastian>So, yeah, one of the main things in the beginning, I thought,

00:25:30.390 --> 00:25:34.110
<v Sebastian>ah, it's so cool. Like, I can't get wrong with this.

00:25:34.210 --> 00:25:37.090
<v Sebastian>If my code compiles, it's perfect.

00:25:37.250 --> 00:25:41.850
<v Sebastian>And it's true in most of the cases, but some logic bugs can still sneak in.

00:25:42.590 --> 00:25:46.350
<v Sebastian>Mostly if you don't write your code in a way that prevents them because that's

00:25:46.350 --> 00:25:51.250
<v Sebastian>one of the cool things about Rust and what we use extensively here as well, if you write your code,

00:25:52.170 --> 00:25:55.570
<v Sebastian>Using the strong type guarantees,

00:25:55.890 --> 00:25:59.890
<v Sebastian>you can make it so that any invariants that need to hold true,

00:26:00.050 --> 00:26:05.250
<v Sebastian>so any preconditions that your code has and that need to be true for it to work

00:26:05.250 --> 00:26:07.870
<v Sebastian>correctly, you can express that in the type system.

00:26:08.190 --> 00:26:10.450
<v Sebastian>Maybe not all of them, but most of them.

00:26:11.010 --> 00:26:14.250
<v Sebastian>And so, for example, we use that extensively for configuration.

00:26:14.250 --> 00:26:20.270
<v Sebastian>We have things, we have code that can only run once the hardware is initialized correctly.

00:26:20.270 --> 00:26:28.250
<v Sebastian>And so we pass around serial-sized tokens, types that can only get created in

00:26:28.250 --> 00:26:32.290
<v Sebastian>one place in the system, and that's after initialization of that specific hardware.

00:26:32.570 --> 00:26:38.170
<v Sebastian>And so we use, for example, this sort of a token in other places to prove,

00:26:38.290 --> 00:26:42.070
<v Sebastian>yes, this code will only ever run after initializing that specific hardware.

00:26:43.010 --> 00:26:45.450
<v Matthias>Couldn't you also use a type state pattern for that?

00:26:47.010 --> 00:26:50.630
<v Sebastian>Well if you do that type state pattern you kind of,

00:26:51.850 --> 00:26:56.690
<v Sebastian>You kind of make code dependent. You encapsulate the code. Not encapsulate.

00:26:56.850 --> 00:26:59.590
<v Sebastian>You make it dependent on each other a lot more, I feel like.

00:27:00.250 --> 00:27:05.090
<v Sebastian>So instead of writing a huge state machine, basically, like that,

00:27:05.270 --> 00:27:11.770
<v Sebastian>you can write your code more freely, just at any given structure that you want,

00:27:12.150 --> 00:27:14.410
<v Sebastian>just passing around these types of keys.

00:27:14.970 --> 00:27:19.330
<v Matthias>Yeah, I never heard about that types with keys pattern, the token pattern that

00:27:19.330 --> 00:27:25.050
<v Matthias>you described. Is that a thing that you invented, or does it come from any other project?

00:27:25.730 --> 00:27:30.710
<v Sebastian>Well, it's definitely used in the embedded world a lot.

00:27:30.850 --> 00:27:38.070
<v Sebastian>Maybe not in the same kind of way, but we've got the idea from crates like Embassy

00:27:38.070 --> 00:27:43.990
<v Sebastian>and actually various hardware abstraction layer crates that if you,

00:27:44.310 --> 00:27:49.330
<v Sebastian>in the beginning, they give you one struct that contains all of the peripherals

00:27:49.330 --> 00:27:54.950
<v Sebastian>but it's just zero-sized types for these peripherals and the idea behind that

00:27:54.950 --> 00:28:00.870
<v Sebastian>is that you can then when you want to use one of these peripherals you have to consume that type.

00:28:01.690 --> 00:28:05.430
<v Sebastian>And that prevents you from using the same peripheral twice,

00:28:05.530 --> 00:28:08.670
<v Sebastian>for example pins if you think about a microcontroller

00:28:08.670 --> 00:28:11.870
<v Sebastian>it has pins that you can toggle on or off and if

00:28:11.870 --> 00:28:14.650
<v Sebastian>you decided at one point yes okay i'm gonna use this

00:28:14.650 --> 00:28:17.510
<v Sebastian>pin to i don't know to talk to a motor for example

00:28:17.510 --> 00:28:20.230
<v Sebastian>and then later you think okay right i

00:28:20.230 --> 00:28:23.770
<v Sebastian>have a i have another use for a pin maybe i

00:28:23.770 --> 00:28:27.230
<v Sebastian>don't know i want to toggle an led or something let me

00:28:27.230 --> 00:28:32.650
<v Sebastian>see ah maybe pin one is still available i'm gonna try to use it ah no i've already

00:28:32.650 --> 00:28:37.090
<v Sebastian>used this before and rust tells you this because you moved the type you moved

00:28:37.090 --> 00:28:42.110
<v Sebastian>the variable into the function that used it and so you can't use it later and

00:28:42.110 --> 00:28:44.110
<v Sebastian>so that's that's kind of the the same idea.

00:28:44.370 --> 00:28:51.250
<v Sebastian>You have a token for each peripheral, for each pin that you can only use once. And you

00:28:51.640 --> 00:28:57.340
<v Sebastian>This is one of the things I really love about Rust. It's the ability to detect

00:28:57.340 --> 00:28:59.400
<v Sebastian>these kind of configuration errors at compile time.

00:28:59.640 --> 00:29:04.800
<v Sebastian>I mean, the compiler literally prevents you from writing codes that is wrongly

00:29:04.800 --> 00:29:09.580
<v Sebastian>configured that would be valid code just from a processor perspective.

00:29:09.980 --> 00:29:13.480
<v Sebastian>I mean, it's okay if you use the same pin for two different things.

00:29:14.900 --> 00:29:19.480
<v Sebastian>You can write to the registers and it's not going to care. But the end result

00:29:19.480 --> 00:29:23.400
<v Sebastian>is that the pin is not going to do what you want because you're using it for

00:29:23.400 --> 00:29:25.160
<v Sebastian>two things at the same time.

00:29:25.820 --> 00:29:32.280
<v Sebastian>And by expressing this notion of only one part of your program can use this

00:29:32.280 --> 00:29:38.220
<v Sebastian>specific thing via a token, the compiler can ensure that this, in fact, is the case.

00:29:39.820 --> 00:29:45.580
<v Matthias>Now I understand part about loosely coupled components as well because I'm not

00:29:45.580 --> 00:29:53.080
<v Matthias>sure, but I guess Embassy used the type state pattern and a lot of generics for the pins before.

00:29:53.280 --> 00:29:56.720
<v Matthias>I'm not sure if they dialed it down a bit or dialed it back because,

00:29:58.110 --> 00:30:02.250
<v Matthias>sometimes want to repurpose pins and if

00:30:02.250 --> 00:30:05.150
<v Matthias>you set up your system once it's not

00:30:05.150 --> 00:30:08.190
<v Matthias>as flexible as if you were to be able to

00:30:08.190 --> 00:30:11.370
<v Matthias>you know change that dynamically sort

00:30:11.370 --> 00:30:19.490
<v Matthias>of and at the same time you just use the normal ownership rules in rust to enforce

00:30:19.490 --> 00:30:23.050
<v Matthias>the same behavior so you can still encode it in the type system without really

00:30:23.050 --> 00:30:28.510
<v Matthias>having a lot of overhead and a lot of complexity on the on the type system level.

00:30:28.510 --> 00:30:31.730
<v Sebastian>Exactly yes we as i

00:30:31.730 --> 00:30:34.990
<v Sebastian>said we use this in a bunch of places also for example for

00:30:34.990 --> 00:30:37.750
<v Sebastian>wrapping c libraries it's kind of

00:30:37.750 --> 00:30:40.770
<v Sebastian>an interesting thing we during our

00:30:40.770 --> 00:30:44.390
<v Sebastian>Gama Alpha project we used a communication

00:30:44.390 --> 00:30:47.650
<v Sebastian>protocol called CSP and unfortunately

00:30:47.650 --> 00:30:50.530
<v Sebastian>at the time there was no pure rust implementation of it

00:30:50.530 --> 00:30:53.850
<v Sebastian>so we had no choice but to wrap

00:30:53.850 --> 00:30:57.070
<v Sebastian>well either implement the whole thing ourselves but that would

00:30:57.070 --> 00:31:00.470
<v Sebastian>have taken quite a bit of time which we didn't have or

00:31:00.470 --> 00:31:03.430
<v Sebastian>to wrap the the c library and the c library has

00:31:03.430 --> 00:31:06.490
<v Sebastian>a bunch of invariants when you use it you have one

00:31:06.490 --> 00:31:09.870
<v Sebastian>of them is you have to call a function called csp_init before

00:31:09.870 --> 00:31:12.650
<v Sebastian>you do anything else and so this kind of a thing once

00:31:12.650 --> 00:31:15.990
<v Sebastian>again we we have a series struct in

00:31:15.990 --> 00:31:18.950
<v Sebastian>rust called CSP it has an init function and it

00:31:18.950 --> 00:31:23.750
<v Sebastian>gives you is the only place where you can get an instance of this CSP struct

00:31:23.750 --> 00:31:29.910
<v Sebastian>and then the CSP struct allows you to call other functions on itself but you

00:31:29.910 --> 00:31:34.510
<v Sebastian>need a self so you need an instance of the struct and so that proves that you

00:31:34.510 --> 00:31:37.590
<v Sebastian>have initialized the CSP the underlying c library.

00:31:38.170 --> 00:31:41.850
<v Matthias>Because that's sort of the only place where you can get that token.

00:31:41.850 --> 00:31:48.810
<v Sebastian>From there's only one place to get this token and in that place we initialized

00:31:48.810 --> 00:31:49.650
<v Sebastian>the library just before.

00:31:50.570 --> 00:31:57.250
<v Sebastian>So it's kind of a way of you have one place in your code where you know about

00:31:57.250 --> 00:31:59.730
<v Sebastian>these invariants and you only need to take,

00:32:00.810 --> 00:32:03.650
<v Sebastian>to express these invariants at that place

00:32:03.650 --> 00:32:06.530
<v Sebastian>so if i for example if i have function of this library

00:32:06.530 --> 00:32:09.730
<v Sebastian>and i know it needs to be initialized before all

00:32:09.730 --> 00:32:13.130
<v Sebastian>i need to do is i need to take a reference to

00:32:13.130 --> 00:32:16.090
<v Sebastian>to this token and that guarantees

00:32:16.090 --> 00:32:21.710
<v Sebastian>me yes the library has to be initialized and so as a user of this library which

00:32:21.710 --> 00:32:26.010
<v Sebastian>is also us but sometimes we can forget maybe you forget that you have to initialize

00:32:26.010 --> 00:32:30.530
<v Sebastian>the library before or you're just you know you're moving one line of code a

00:32:30.530 --> 00:32:35.630
<v Sebastian>few lines up by accident before the initialization because you think, ah, this might be,

00:32:36.290 --> 00:32:38.330
<v Sebastian>more efficient that way or something like that.

00:32:38.470 --> 00:32:41.270
<v Sebastian>You forget about these environments much too easy.

00:32:41.530 --> 00:32:45.350
<v Sebastian>But by encoding them into the type system and by encoding them into the function

00:32:45.350 --> 00:32:50.830
<v Sebastian>signatures, we can still enforce it and we can let the compiler help us in not forgetting about it.

00:32:52.170 --> 00:32:56.630
<v Matthias>That's pretty impressive. At the risk of going a bit meta here,

00:32:56.850 --> 00:32:59.650
<v Matthias>how do you come up with these patterns?

00:33:00.090 --> 00:33:05.070
<v Matthias>Do you find them online in certain other crates?

00:33:05.270 --> 00:33:10.470
<v Matthias>Or do you think really hard about those problems and then start to encode those invariants?

00:33:10.670 --> 00:33:12.770
<v Matthias>It's not really discoverable.

00:33:13.570 --> 00:33:21.450
<v Sebastian>Yeah. So I think the way we discover them is by failing, by writing code that

00:33:21.450 --> 00:33:25.190
<v Sebastian>is invalid and where we then introduce certain bugs.

00:33:25.190 --> 00:33:30.750
<v Sebastian>And then later discovering, ah, yeah, okay, we need to prevent us from ever

00:33:30.750 --> 00:33:32.750
<v Sebastian>writing that code again. And so...

00:33:34.200 --> 00:33:38.860
<v Sebastian>For example, with the case of the library, it was literally the case that we

00:33:38.860 --> 00:33:40.660
<v Sebastian>called the function before we initialized it.

00:33:41.100 --> 00:33:44.100
<v Sebastian>And so that's how we got the idea of, okay, we need to prevent that.

00:33:44.320 --> 00:33:49.900
<v Sebastian>How do we prevent that? Let's use this token system. Invest.

00:33:51.200 --> 00:33:55.340
<v Matthias>Do you write down those correctness guidelines somewhere?

00:33:56.760 --> 00:34:03.100
<v Sebastian>Well, we do have a bunch of rules like that, but the point is you only have to write them in code.

00:34:03.100 --> 00:34:09.540
<v Sebastian>Right so the once once you corrected that mistake once you made sure via the

00:34:09.540 --> 00:34:15.400
<v Sebastian>type system that it's impossible to use a function in an incorrect state you

00:34:15.400 --> 00:34:18.660
<v Sebastian>don't have to you don't have to write anything anymore because the compiler will enforce it.

00:34:18.660 --> 00:34:27.880
<v Matthias>Well i guess you review a lot of rust code nowadays a lot of rust code that should or cannot fail,

00:34:29.540 --> 00:34:35.700
<v Matthias>how do you review rust code for correctness what do you look out for what are

00:34:35.700 --> 00:34:38.400
<v Matthias>some common patterns that you found useful here.

00:34:38.400 --> 00:34:42.280
<v Sebastian>Yeah for reviewing i

00:34:42.280 --> 00:34:45.300
<v Sebastian>like to to think about

00:34:45.300 --> 00:34:48.300
<v Sebastian>all possible states that a certain

00:34:48.300 --> 00:34:51.640
<v Sebastian>rust code can be in and all possible inputs it's

00:34:51.640 --> 00:34:54.460
<v Sebastian>kind of like like fuzzing you know where you

00:34:54.460 --> 00:34:57.900
<v Sebastian>but but manually fuzzing we we

00:34:57.900 --> 00:35:00.680
<v Sebastian>like to split up our our code and our

00:35:00.680 --> 00:35:07.440
<v Sebastian>metric as into small chunks and so it's relatively easy usually for us to to

00:35:07.440 --> 00:35:11.260
<v Sebastian>think about all the possible inputs and what can go wrong and then i like to

00:35:11.260 --> 00:35:18.320
<v Sebastian>make sure that we use the type system to its full extent and to encode any preconditions

00:35:18.320 --> 00:35:20.600
<v Sebastian>as i said into into the types.

00:35:20.760 --> 00:35:24.460
<v Sebastian>It's kind of like if you have a precondition for using a value that can't be

00:35:24.460 --> 00:35:27.140
<v Sebastian>zero, in Rust, you have the non-zero type.

00:35:27.960 --> 00:35:32.040
<v Sebastian>So Rust itself uses a lot of these types for preconditions as well.

00:35:32.340 --> 00:35:38.260
<v Sebastian>Same with the C string, a string that has to be zero, null byte terminated.

00:35:38.900 --> 00:35:41.600
<v Sebastian>So Rust itself gives us a lot of these ideas as well.

00:35:41.820 --> 00:35:47.260
<v Sebastian>And so when I examine code, I'm just trying to think of all of these different

00:35:47.260 --> 00:35:49.780
<v Sebastian>invariants that need to hold true for a specific code.

00:35:49.880 --> 00:35:55.380
<v Sebastian>I'm trying to find them out and make sure that they're expressed as much as possible.

00:35:56.000 --> 00:35:58.100
<v Matthias>Are you a friend of debug assertions?

00:36:00.040 --> 00:36:06.860
<v Sebastian>Yes. Well, I mean, we use them extensively as well, but only in places where

00:36:06.860 --> 00:36:11.160
<v Sebastian>we can't guarantee something just with the type system.

00:36:11.300 --> 00:36:16.680
<v Sebastian>I mean, there's always certain things that you can't guarantee at compile time,

00:36:16.940 --> 00:36:19.180
<v Sebastian>especially if you're interacting with hardware, right?

00:36:19.500 --> 00:36:23.880
<v Sebastian>Some of these things you just can't do with just the type system.

00:36:24.000 --> 00:36:24.540
<v Matthias>For example?

00:36:24.540 --> 00:36:29.880
<v Sebastian>Some of the runtime state that can't be known at compile time,

00:36:30.080 --> 00:36:32.460
<v Sebastian>we, for example, have our own heap.

00:36:32.740 --> 00:36:37.760
<v Sebastian>And so the idea of a heap is that you have a bunch of memory available and you

00:36:37.760 --> 00:36:41.500
<v Sebastian>at runtime allocate things out of that heap as needed.

00:36:42.000 --> 00:36:47.860
<v Sebastian>And you can never kind of really be sure how much you allocate just from looking

00:36:47.860 --> 00:36:50.560
<v Sebastian>at your code because it depends on timing.

00:36:50.760 --> 00:36:54.200
<v Sebastian>It depends on when certain pieces of code need certain amount of memories.

00:36:54.540 --> 00:36:57.700
<v Sebastian>And so for those kind of,

00:36:58.860 --> 00:37:03.640
<v Sebastian>So if we request a piece of memory, but we don't have any more,

00:37:03.700 --> 00:37:09.160
<v Sebastian>for example, like this, there has to be still debug assertions.

00:37:09.440 --> 00:37:13.000
<v Sebastian>And in fact, Rust itself brings a lot of debug assertions as well.

00:37:13.340 --> 00:37:18.360
<v Sebastian>Every time you access an array, for example, or a slice, you have debug assertions

00:37:18.360 --> 00:37:25.000
<v Sebastian>that make sure that you don't go over any of the limits in memory.

00:37:25.080 --> 00:37:27.980
<v Sebastian>And that's one of the strong systems of Rust as well.

00:37:27.980 --> 00:37:31.100
<v Sebastian>That's the memory safety all of

00:37:31.100 --> 00:37:38.380
<v Sebastian>these checks at runtime as well of course you can disable them but this is for

00:37:38.380 --> 00:37:46.520
<v Sebastian>us it's a tradeoff of size versus security and for the Gama Alpha project at

00:37:46.520 --> 00:37:50.280
<v Sebastian>least we were able to leave debug assertions on.

00:37:51.440 --> 00:37:55.360
<v Sebastian>Because that's another part of the space industry.

00:37:55.660 --> 00:38:00.480
<v Sebastian>Usually you work with hardware that is not like your modern laptops and computers,

00:38:00.660 --> 00:38:03.700
<v Sebastian>where you have basically unlimited memory and space.

00:38:03.860 --> 00:38:07.560
<v Sebastian>No, our programs need to fit in tiny flash memories.

00:38:08.140 --> 00:38:13.080
<v Sebastian>And so removing debug assertions can be one of the ways where you can have more

00:38:13.080 --> 00:38:16.200
<v Sebastian>actual code, but with a smaller size.

00:38:16.820 --> 00:38:19.220
<v Matthias>And by tiny, you mean how large?

00:38:20.000 --> 00:38:23.520
<v Sebastian>Think like a couple hundred kilobytes oh wow

00:38:23.520 --> 00:38:26.400
<v Sebastian>yeah it kind of depends i mean for for the

00:38:26.400 --> 00:38:29.320
<v Sebastian>alpha satellite we had i think so the

00:38:29.320 --> 00:38:32.540
<v Sebastian>processor itself had an integrated flash memory

00:38:32.540 --> 00:38:36.840
<v Sebastian>of 256 kilobytes and

00:38:36.840 --> 00:38:40.600
<v Sebastian>then we had an external chip with i

00:38:40.600 --> 00:38:44.320
<v Sebastian>think an additional one megabyte of flash if

00:38:44.320 --> 00:38:47.660
<v Sebastian>i'm not mistaken so not a lot of space

00:38:47.660 --> 00:38:50.660
<v Sebastian>and some of the some of the space you need for for

00:38:50.660 --> 00:38:53.860
<v Sebastian>data as well because yeah in you

00:38:53.860 --> 00:38:58.520
<v Sebastian>talked about this in a previous episode you talked with i think ksat a provider

00:38:58.520 --> 00:39:03.180
<v Sebastian>of ground stations so you might be familiar already but the satellite doesn't

00:39:03.180 --> 00:39:08.280
<v Sebastian>have a direct communication to the ground all of the time we also need to store

00:39:08.280 --> 00:39:12.160
<v Sebastian>data on the satellite itself before we can pass it down to the ground stations.

00:39:13.270 --> 00:39:17.350
<v Matthias>Okay. It turns out there's not a lot of space in space.

00:39:18.910 --> 00:39:24.190
<v Matthias>You work on tiny hardware. And shout out to Vegard as well. It was an amazing episode too.

00:39:25.010 --> 00:39:29.850
<v Matthias>Now, Rust has fallible allocations for vectors nowadays.

00:39:30.310 --> 00:39:36.270
<v Matthias>But I'm guessing that you even want to avoid allocations in the first place,

00:39:36.510 --> 00:39:38.450
<v Matthias>especially the dynamic allocations.

00:39:38.450 --> 00:39:44.650
<v Matthias>And Oxide, for example, has a scheduler called Hubris and Steve,

00:39:44.830 --> 00:39:47.910
<v Matthias>please correct me if I'm wrong here but Steve Klapnik, that is.

00:39:48.310 --> 00:39:53.810
<v Matthias>I think what they did was they used static allocation,

00:39:53.990 --> 00:39:59.650
<v Matthias>static memory and every payload that they run on that scheduler has a fixed

00:39:59.650 --> 00:40:05.310
<v Matthias>size known at compile time which allows you to have predictable allocations.

00:40:05.730 --> 00:40:08.410
<v Matthias>Do you use that pattern as well? if you can?

00:40:08.890 --> 00:40:15.650
<v Matthias>So having a fixed struct and knowing that only this struct will need to be allocated,

00:40:15.810 --> 00:40:17.230
<v Matthias>quote unquote, on the stack?

00:40:17.530 --> 00:40:24.250
<v Sebastian>Yes, as much as possible. So whenever we can use it, we try to avoid the allocations

00:40:24.250 --> 00:40:25.570
<v Sebastian>and just use stack variables.

00:40:25.870 --> 00:40:32.550
<v Sebastian>Or we have our own stack allocated statically and use elements out of that.

00:40:32.850 --> 00:40:37.510
<v Sebastian>But sometimes it's just not possible to know at compile time,

00:40:37.730 --> 00:40:41.150
<v Sebastian>what kind of, how much memory you need to use.

00:40:41.310 --> 00:40:45.170
<v Sebastian>For example, think about the telecommand stack.

00:40:45.410 --> 00:40:49.370
<v Sebastian>So for the Alpha Satellite, we were able to send telecommands to it.

00:40:49.810 --> 00:40:55.290
<v Sebastian>And on the satellite itself, you don't know how many telecommands will come

00:40:55.290 --> 00:41:02.910
<v Sebastian>in at a given time and how long it takes for each telecommand to be worked on. And so we had a cube.

00:41:03.460 --> 00:41:06.300
<v Sebastian>Of telecommands and this queue of course

00:41:06.300 --> 00:41:09.060
<v Sebastian>has an upper limit but the the memory

00:41:09.060 --> 00:41:12.800
<v Sebastian>out of it was kind of heap allocated you

00:41:12.800 --> 00:41:16.080
<v Sebastian>know because it was it was it had an upper limit but it

00:41:16.080 --> 00:41:20.040
<v Sebastian>was taken out of a big slab but in

00:41:20.040 --> 00:41:22.860
<v Sebastian>in all other cases where we can we really try

00:41:22.860 --> 00:41:25.640
<v Sebastian>to avoid using the heap

00:41:25.640 --> 00:41:28.400
<v Sebastian>i mean that's the no std environment for you you

00:41:28.400 --> 00:41:31.220
<v Sebastian>don't get heap for free you need to provide your own

00:41:31.220 --> 00:41:34.240
<v Sebastian>heap if you need it and so you're very

00:41:34.240 --> 00:41:37.720
<v Sebastian>very specific about the places

00:41:37.720 --> 00:41:41.060
<v Sebastian>that you that you need a heap and

00:41:41.060 --> 00:41:45.580
<v Sebastian>you try to avoid it in all other cases one thing that can help with that a lot

00:41:45.580 --> 00:41:52.200
<v Sebastian>is a crate called zero copy for example in our telecommand and telemetry system

00:41:52.200 --> 00:41:57.620
<v Sebastian>we use it very extensively so the the way it works is you you define your structs

00:41:57.620 --> 00:41:59.020
<v Sebastian>the data that you want to send,

00:41:59.240 --> 00:42:06.620
<v Sebastian>want to be able to send, and we use zero copy to convert them or let them be

00:42:06.620 --> 00:42:12.300
<v Sebastian>converted safely into bytes and from bytes without the use of an extra buffer,

00:42:12.460 --> 00:42:14.000
<v Sebastian>without the use of an extra allocation.

00:42:14.360 --> 00:42:18.440
<v Sebastian>Just the same amount of memory. It's basically a safer transmute.

00:42:20.540 --> 00:42:25.020
<v Sebastian>And so, because we need to send the data as bytes, obviously,

00:42:25.200 --> 00:42:29.600
<v Sebastian>so we need to do this conversion to and from bytes and zero copy is a great

00:42:29.600 --> 00:42:33.440
<v Sebastian>help for that sort of work if.

00:42:33.440 --> 00:42:38.360
<v Matthias>I understand correctly that means you don't initialize the struct you have a

00:42:38.360 --> 00:42:46.440
<v Matthias>view into this byte block in this block of bytes and zero copy kind of makes that safe for you.

00:42:46.440 --> 00:42:53.800
<v Sebastian>Yes in in a way so there's two ways of using it first of all the easy way is

00:42:53.800 --> 00:42:55.520
<v Sebastian>you already have a struct and

00:42:55.520 --> 00:42:59.000
<v Sebastian>you want to convert it into bytes and send those bytes over the network.

00:42:59.620 --> 00:43:02.260
<v Sebastian>ZeroCopy helps you with that. But then the other way around...

00:43:03.320 --> 00:43:08.260
<v Sebastian>You receive a bunch of bytes, and then you want to pass these bytes as a struct.

00:43:09.320 --> 00:43:16.800
<v Sebastian>And ZeroCopy makes this passing, this conversion from just a view of the bytes

00:43:16.800 --> 00:43:19.900
<v Sebastian>into a reference to the actual struct possible and save.

00:43:20.500 --> 00:43:24.420
<v Sebastian>By making sure that there's no invariants that can't be uphold.

00:43:24.920 --> 00:43:28.780
<v Sebastian>Or in newer versions, at the time they didn't have that, but in newer versions

00:43:28.780 --> 00:43:34.880
<v Sebastian>you have a try-variant of all of their functions, which allows to test for certain invariants.

00:43:34.960 --> 00:43:38.460
<v Sebastian>For example, if you want to receive a Boolean, a Boolean can either be 1 or

00:43:38.460 --> 00:43:42.440
<v Sebastian>0, but a byte can be 0 to 255, right?

00:43:42.720 --> 00:43:46.520
<v Sebastian>So you have a bunch more values that normally shouldn't be allowed,

00:43:47.640 --> 00:43:49.560
<v Sebastian>and these need to be verified.

00:43:49.820 --> 00:43:52.960
<v Sebastian>And that's also one of the critical things.

00:43:54.020 --> 00:44:02.400
<v Sebastian>In C, I saw a bunch of code where you just convert from your bytes into integers

00:44:02.400 --> 00:44:09.040
<v Sebastian>and then you use those integers somewhere else and so it's very easy to mess up.

00:44:10.220 --> 00:44:14.000
<v Sebastian>With just not validating your inputs enough.

00:44:14.420 --> 00:44:17.840
<v Sebastian>And especially if you accept input over satellite connection,

00:44:18.060 --> 00:44:19.740
<v Sebastian>there's a bunch of bits that can flip.

00:44:19.920 --> 00:44:23.740
<v Sebastian>There's a bunch of stuff that can just go wrong. And so you really need to be

00:44:23.740 --> 00:44:27.040
<v Sebastian>sure to pass it correctly.

00:44:27.300 --> 00:44:33.520
<v Sebastian>And once again, we can use Rust's type system by making the constructors to

00:44:33.520 --> 00:44:39.240
<v Sebastian>all of these payload structs private and letting it just take bytes and doing

00:44:39.240 --> 00:44:42.980
<v Sebastian>all of this validation in this new function, in the constructor,

00:44:43.760 --> 00:44:48.740
<v Sebastian>and returning an option of ourself or a result of ourself.

00:44:48.880 --> 00:44:52.860
<v Sebastian>And so if any of the preconditions, they're just local, they're right next to

00:44:52.860 --> 00:44:56.580
<v Sebastian>the struct, so it's easy to verify that all of the preconditions that we need

00:44:56.580 --> 00:45:00.060
<v Sebastian>when converting from a byte string are checked for.

00:45:00.320 --> 00:45:05.040
<v Sebastian>And then afterwards, you're sure if you have this struct, its data is validated.

00:45:06.010 --> 00:45:11.650
<v Matthias>Well, that's really nice. It's a nice example of making illegal state impossible

00:45:11.650 --> 00:45:15.830
<v Matthias>to represent and parsing instead of validating. That's kind of cool.

00:45:16.110 --> 00:45:21.410
<v Matthias>You said that zero copy is a bit like a safe transmute.

00:45:21.910 --> 00:45:27.010
<v Matthias>Would that mean you can ditch transmute altogether and always use zero copy?

00:45:27.170 --> 00:45:31.830
<v Matthias>Or are there any cases where zero copy just doesn't provide a safe interface?

00:45:32.850 --> 00:45:36.130
<v Sebastian>Actually, we have no instances of transmute.

00:45:36.490 --> 00:45:41.110
<v Sebastian>And it's on the list of things that we really try to avoid.

00:45:41.470 --> 00:45:47.230
<v Sebastian>And so far, we have not come across a use case that is not covered by a zero copy.

00:45:47.770 --> 00:45:54.110
<v Sebastian>So, of course, sometimes we have to convert between different types in Rust, and we use as for that.

00:45:54.270 --> 00:45:57.150
<v Sebastian>But those are safer conversions than just using transmute.

00:45:58.130 --> 00:46:04.810
<v Sebastian>And the fact that the type system guarantees no just random conversion between

00:46:04.810 --> 00:46:11.610
<v Sebastian>different types is really helpful to reason about these invariants in your code.

00:46:12.210 --> 00:46:17.670
<v Sebastian>So, for example, just think about in C, I can create any struct at any point in any time.

00:46:18.190 --> 00:46:23.510
<v Sebastian>In Rust, you need unsafe to do it. And it's a big kind of flag.

00:46:23.510 --> 00:46:31.450
<v Sebastian>If you see unsafe in the code, it helps you during the review because when you

00:46:31.450 --> 00:46:34.430
<v Sebastian>use unsafe, you always need to prove, at least with a comment,

00:46:34.990 --> 00:46:37.350
<v Sebastian>that certain invariants are holding up.

00:46:38.120 --> 00:46:42.320
<v Sebastian>And that makes it very easy to prove that your code can be safe,

00:46:42.400 --> 00:46:43.500
<v Sebastian>even if you're using unsafe.

00:46:43.860 --> 00:46:49.860
<v Sebastian>So unfortunately, we still have C libraries underneath, which are all unsafe.

00:46:50.120 --> 00:46:53.460
<v Sebastian>I mean, it's C code, so there's no help from the Rust compiler there.

00:46:53.860 --> 00:46:58.540
<v Sebastian>And so interfacing with those does require unsafe boundaries, unsafe blocks.

00:47:00.140 --> 00:47:05.640
<v Sebastian>But when we write our wrapper functions for these functions in the C libraries,

00:47:05.960 --> 00:47:10.920
<v Sebastian>we make sure that all of the unsafe free conditions that need to be met for

00:47:10.920 --> 00:47:13.520
<v Sebastian>this library to be called are met.

00:47:13.720 --> 00:47:18.000
<v Sebastian>And one of the examples is, as I said, the CSP library, where we make sure that

00:47:18.000 --> 00:47:19.840
<v Sebastian>it's initialized before we use any of the functions.

00:47:20.480 --> 00:47:26.140
<v Matthias>Okay, you try to minimize unsafe code. Do you also try to minimize unwraps?

00:47:26.380 --> 00:47:28.360
<v Matthias>Are there any better patterns that you use?

00:47:28.540 --> 00:47:35.300
<v Sebastian>Yeah. So unwraps, direct unwraps are also somewhat forbidden in our code.

00:47:35.620 --> 00:47:40.340
<v Sebastian>The best that we can do are expects, where you provide a message and a reasoning

00:47:40.340 --> 00:47:43.500
<v Sebastian>of why this certain thing can never fail.

00:47:43.980 --> 00:47:49.400
<v Sebastian>And there's still a few pain points in Rust with this, where you do need to unwrap certain things.

00:47:49.620 --> 00:47:52.480
<v Sebastian>For example, think about creating a non-zero value.

00:47:52.940 --> 00:47:58.040
<v Sebastian>You can do this unwrapping or this expecting in const code, which is very nice.

00:47:58.540 --> 00:48:03.980
<v Sebastian>So you can make it a compile time error. Yet still, it's unfortunate that certain

00:48:03.980 --> 00:48:08.860
<v Sebastian>things can't be expressed as you want them and need to be unwrapped.

00:48:08.920 --> 00:48:11.760
<v Sebastian>But we are constantly fighting that.

00:48:12.500 --> 00:48:21.040
<v Sebastian>For example, in cases where we do need a buffer for certain things and we know

00:48:21.040 --> 00:48:25.480
<v Sebastian>beforehand that we need a certain size, you can,

00:48:27.280 --> 00:48:32.980
<v Sebastian>Add certain trade bounds using the unstable const generic features that prevent

00:48:32.980 --> 00:48:37.840
<v Sebastian>you from needing to use Unwrap and then just giving you the actual value that

00:48:37.840 --> 00:48:40.180
<v Sebastian>you want without using a result or an option.

00:48:40.480 --> 00:48:46.840
<v Sebastian>And that's only possible because you let the compiler validate these preconditions at compile time.

00:48:47.100 --> 00:48:51.140
<v Matthias>In my mind, you learned Rust in hardcore mode. it's

00:48:51.140 --> 00:48:55.620
<v Matthias>in the space industry as a startup straight

00:48:55.620 --> 00:49:00.580
<v Matthias>out of university with a python background and then also needing to ship features

00:49:00.580 --> 00:49:07.820
<v Matthias>really early on you know working there what would you recommend others to do

00:49:07.820 --> 00:49:13.620
<v Matthias>on how to learn rust effectively learning quickly learn it well how how would

00:49:13.620 --> 00:49:14.960
<v Matthias>flatten the learning curve?

00:49:17.180 --> 00:49:21.760
<v Sebastian>Flattening the learning curve, that's a big kind of issue in Rust,

00:49:21.900 --> 00:49:24.420
<v Sebastian>I would say, compared to Python, for example.

00:49:25.920 --> 00:49:35.360
<v Sebastian>I think just trying things out and learning by example is the easiest way to do.

00:49:35.460 --> 00:49:39.200
<v Sebastian>Unfortunately, I don't have a fix, like a solution for everyone.

00:49:39.420 --> 00:49:46.740
<v Sebastian>But the thing is, struggling a bit with the compiler is a bit frustrating in

00:49:46.740 --> 00:49:50.400
<v Sebastian>the beginning, but it's a very valuable learning experience.

00:49:50.400 --> 00:49:57.980
<v Sebastian>So if you start out using Rust and you're having trouble with lifetimes,

00:49:58.220 --> 00:50:03.380
<v Sebastian>with borrowing, whatever, it is the compiler trying to help you.

00:50:03.640 --> 00:50:09.280
<v Sebastian>And once you realize this, once you understand that the structures and the ways

00:50:09.280 --> 00:50:15.720
<v Sebastian>you did it before are a little bit flawed in regard, once you understand this, it does help you.

00:50:15.720 --> 00:50:20.700
<v Sebastian>Unfortunately, it is a hard pill to swallow sometimes, but it's very useful.

00:50:21.000 --> 00:50:25.720
<v Sebastian>I, myself, after learning Rust this way, have come back to various Python projects

00:50:25.720 --> 00:50:31.720
<v Sebastian>and found out that code that I thought was perfectly fine, that I wrote many years ago,

00:50:32.460 --> 00:50:37.800
<v Sebastian>actually had subtle problems that could occur under some circumstances.

00:50:38.000 --> 00:50:43.580
<v Sebastian>Not all of the time, but sometimes. And so these, for example,

00:50:43.740 --> 00:50:48.220
<v Sebastian>if you have multiple threads and you access certain variables for multiple threads

00:50:48.220 --> 00:50:52.900
<v Sebastian>in Python, there's very little help for you to avoid...

00:50:54.070 --> 00:50:59.110
<v Sebastian>Accessing a variable at the same time as in fact there's none you need to do that yourself,

00:50:59.650 --> 00:51:04.050
<v Sebastian>and in rust you can let the compiler help you with that and initially of course

00:51:04.050 --> 00:51:08.910
<v Sebastian>it's it's harder because you need to prove that you're doing you're doing these

00:51:08.910 --> 00:51:14.910
<v Sebastian>things in a safe way but it does help you to avoid certain logic bugs that would

00:51:14.910 --> 00:51:17.450
<v Sebastian>be easily to would be easy to make otherwise.

00:51:18.550 --> 00:51:21.290
<v Matthias>So see the compiler as an ally.

00:51:21.290 --> 00:51:21.906
<v Sebastian>Exactly

00:51:21.906 --> 00:51:22.670
<v Matthias>Try to

00:51:22.670 --> 00:51:29.150
<v Matthias>take a step back and take your ego out look at what the compiler is trying to

00:51:29.150 --> 00:51:31.470
<v Matthias>tell you and try to improve.

00:51:32.230 --> 00:51:39.230
<v Sebastian>Actually that's one of the very valuable lessons Rust is amazing and one of

00:51:39.230 --> 00:51:42.910
<v Sebastian>the main things is the compiler helping you so much and once you understand

00:51:42.910 --> 00:51:47.910
<v Sebastian>that it's not you versus the compiler but it's you and the compiler versus bugs,

00:51:47.930 --> 00:51:54.110
<v Sebastian>then you have a much easier time moving forward, even if it takes a bit of time

00:51:54.110 --> 00:51:55.490
<v Sebastian>to get there, admittedly.

00:51:56.130 --> 00:52:01.550
<v Matthias>100% sure that there are people out there who would like to send in a job application

00:52:01.550 --> 00:52:04.230
<v Matthias>right away or would like to work in that space.

00:52:05.620 --> 00:52:10.840
<v Matthias>What are some next projects for Gama? Things that the team will be working on?

00:52:11.620 --> 00:52:16.580
<v Matthias>Maybe also on the Rust side, what are the next challenges? What's coming up?

00:52:17.840 --> 00:52:25.580
<v Sebastian>Yeah, so if people are interested in joining Gama, we do have some job applications

00:52:25.580 --> 00:52:30.160
<v Sebastian>usually on our website, gamaspace.com so that's where people can find us.

00:52:31.020 --> 00:52:35.520
<v Sebastian>So right now the Gama Alpha satellite actually has been, the work on it has

00:52:35.620 --> 00:52:41.780
<v Sebastian>been finished for more than a year and we are moving forward with a different kind of sail,

00:52:42.580 --> 00:52:48.580
<v Sebastian>a so-called drag sail which is a is a way of de-orbiting a satellite so bringing

00:52:48.580 --> 00:52:53.260
<v Sebastian>a satellite into lower atmosphere where it can burn up so that it doesn't take

00:52:53.260 --> 00:52:57.680
<v Sebastian>up any space anymore in space because even though space is rust the space around

00:52:57.680 --> 00:53:02.060
<v Sebastian>earth is not and yes so there's there's a need for cleaning that up.

00:53:02.060 --> 00:53:07.120
<v Matthias>Does that mean Rust does not have a garbage collector but you

00:53:07.120 --> 00:53:08.000
<v Matthias>use it as a garbage

00:53:09.160 --> 00:53:10.360
<v Sebastian>In a

00:53:10.360 --> 00:53:16.480
<v Sebastian>way i guess although i must say so for this product that we are developing there

00:53:16.480 --> 00:53:25.100
<v Sebastian>and actually that has already been sold in q1 this year we decided that we needed

00:53:25.100 --> 00:53:28.520
<v Sebastian>a lot and like a real lot of reliability.

00:53:29.100 --> 00:53:34.600
<v Sebastian>So this is one of the main drivers of why you need to have this kind of a system.

00:53:34.960 --> 00:53:38.900
<v Sebastian>Your satellite is five years or 10 years in space. There's a lot of radiation,

00:53:39.060 --> 00:53:41.680
<v Sebastian>there's a lot of events and it can fail at any moment.

00:53:41.840 --> 00:53:44.360
<v Sebastian>And so our component needs to be as reliable as possible.

00:53:44.540 --> 00:53:50.720
<v Sebastian>And for that, we decided to have actually no code whatsoever on this product itself.

00:53:50.900 --> 00:53:54.400
<v Sebastian>But that doesn't mean that Rust isn't involved at all. In fact,

00:53:54.700 --> 00:53:59.400
<v Sebastian>all of our test equipment, we have a dedicated little microcontroller and setup

00:53:59.400 --> 00:54:03.300
<v Sebastian>for testing our equipment, is still 100% written in Rust.

00:54:03.890 --> 00:54:09.490
<v Sebastian>Or as much as possible. But the actual drag cell that we're developing right

00:54:09.490 --> 00:54:12.350
<v Sebastian>now is purely based in electronics.

00:54:12.590 --> 00:54:16.430
<v Sebastian>The version that we're doing right now in the future, so the version we're doing

00:54:16.430 --> 00:54:20.350
<v Sebastian>right now is for small satellites, but in the future, the next big project will

00:54:20.350 --> 00:54:25.010
<v Sebastian>likely be a larger version of it using a lot more complicated hardware,

00:54:25.270 --> 00:54:27.510
<v Sebastian>which will require once again software.

00:54:27.850 --> 00:54:33.210
<v Sebastian>And for that, we're going to be able to reuse most of the codes that we've written

00:54:33.210 --> 00:54:37.770
<v Sebastian>for the Alpha satellites, so all of the software stack, the different bootloaders

00:54:37.770 --> 00:54:41.810
<v Sebastian>that we have, the onboard data handling system, most of it can be rewritten,

00:54:42.290 --> 00:54:44.530
<v Sebastian>and so it can be repurposed, basically.

00:54:44.830 --> 00:54:47.550
<v Sebastian>The hardware is going to change a bit, but the.

00:54:48.100 --> 00:54:53.960
<v Sebastian>Because we split up everything into multiple crates, we have a crate specifically

00:54:53.960 --> 00:54:55.640
<v Sebastian>for drivers of the hardware.

00:54:55.800 --> 00:54:58.120
<v Sebastian>So that is the thing that mostly is going to change.

00:54:58.340 --> 00:55:01.180
<v Sebastian>But other logic on top of that can stay the same.

00:55:01.700 --> 00:55:09.380
<v Sebastian>In fact, that's one of the reasons why we split up the organization of our code into so many crates.

00:55:09.500 --> 00:55:14.100
<v Sebastian>We have, I think, 59 crates in total in our internal crate registry.

00:55:14.100 --> 00:55:18.980
<v Sebastian>Not all of them are directly related to the onboard data handling system.

00:55:19.200 --> 00:55:22.220
<v Sebastian>Some of them are also for the test equipment on ground.

00:55:22.520 --> 00:55:32.500
<v Sebastian>But splitting up the codes into well-defined little bits allows us to reuse most of them in space.

00:55:32.660 --> 00:55:35.020
<v Sebastian>It was kind of the idea from the very beginning.

00:55:35.680 --> 00:55:40.900
<v Matthias>Traditionally, the final question is, what's your message to the Rust community?

00:55:42.680 --> 00:55:46.000
<v Sebastian>Well i think that rust

00:55:46.000 --> 00:55:51.780
<v Sebastian>itself is an amazing tool and the rust community is doing an amazing job in

00:55:51.780 --> 00:55:57.120
<v Sebastian>in providing it in in caring for it and also providing no std crates that's

00:55:57.120 --> 00:56:02.280
<v Sebastian>it's very important for for our purpose and i think for for those of you in

00:56:02.280 --> 00:56:05.860
<v Sebastian>the rust community that that provide these crates,

00:56:06.360 --> 00:56:11.180
<v Sebastian>let's try to work on letting the compiler help us as much as possible.

00:56:11.800 --> 00:56:17.380
<v Sebastian>So leaning into constgenerics, leaning into the ability of having these marker

00:56:17.380 --> 00:56:23.480
<v Sebastian>types, because anything that we can handle at compile time is something that

00:56:23.480 --> 00:56:24.220
<v Sebastian>doesn't fail at runtime.

00:56:24.660 --> 00:56:31.900
<v Sebastian>And failing at runtime in a mission-critical environment like space is never a good idea.

00:56:32.060 --> 00:56:37.880
<v Sebastian>So So if we can, let's try to work towards letting the compiler help us as much as possible.

00:56:38.400 --> 00:56:40.960
<v Matthias>Sebastian, thanks a bunch for taking the time.

00:56:41.300 --> 00:56:42.220
<v Sebastian>Thank you very much.

00:56:44.640 --> 00:56:48.020
<v Matthias>And with that, we're closing out Season 5 of Rust in Production.

00:56:48.340 --> 00:56:52.060
<v Matthias>Thanks to all our amazing guests and thanks to you for listening.

00:56:52.380 --> 00:56:58.040
<v Matthias>A special shout-out to Simon Brüggen, who's been editing the show since Episode 1.

00:56:58.480 --> 00:57:02.140
<v Matthias>We'll be back soon with more production stories. In the meantime,

00:57:02.480 --> 00:57:06.060
<v Matthias>if you're thinking about migrating to Rust, we'd love to help.

00:57:06.300 --> 00:57:09.760
<v Matthias>Head over to corrode.dev to learn more. And

00:57:09.760 --> 00:57:14.780
<v Matthias>hey if you enjoyed the show the best way to support us is to leave a review

00:57:14.780 --> 00:57:19.160
<v Matthias>on your favorite podcast platform or share an episode with a colleague or friend

00:57:19.160 --> 00:57:24.700
<v Matthias>it really makes a difference have a nice break we'll see you in season six and

00:57:24.700 --> 00:57:26.960
<v Matthias>thanks for listening to Rust in Production.