Live data from Hacker News

Coroutines make robot code easy

bvisness.me

51–60 of 127 posts

Re: Coroutines make robot code easy

#51

Earlier quoted context omitted.

> I would like to build a rich "process api" that can fork, merge, pause, yield, yield until, drop while, synchronize, wait (latch), react according to events. I feel every distributed systems builds this again and again. Years ago I attempted to build an experimental language with first-class resumable functions. Every function can be invoked by the caller through a special reference type called "quaint". The caller…

I really like this. Thank you for your comment and sharing. I have a lightweight 1:M:N runtime (1 scheduler thread, M kernel threads, N lightweight threads) which preempts by setting hot loops to the limit. https://github.com/samsquire/preemptible-thread (Rust, Java and C) How do you preempt code that is running? Would you like to talk more about your idea?

> How do you preempt code that is running?

It runs in its own VM with custom instructions. The "wait" statement corresponds to a special instruction that is able to switch to a separate execution context and restore the parent context when necessary.

To implement this in native code, some kind of runtime support would be needed. Perhaps a dedicated thread that is able to stop/resume the main thread, changing the contents of the stack and the registers.

Re: Coroutines make robot code easy

#52
As always when this topic comes up, I have to plug Ceu[0] (formerly Céu) and the programming paradigm it represents. It doesn't use coroutines but synchronous concurrency. On top of that it's a reactive language:

    // an external input event channel
    input int KEY;
    
    // par/or concurrently executes two
    // or more blocks (called "trails")
    // if one of them terminates, the
    // other trails are aborted.
    // Compare: par/and, which waits
    // for all trails to terminate
    // before resuming code
    par/or do  
      // an infinite loop that awaits
      // a timer event. Therefore this
      // trail never terminates by itself
      every 1s do
        // Ceu uses C as a host language
        // and compiles to (essentially)
        // a giant finite state machine
        // C functions can be accessed
        // using an underscore prefix
        _printf("Hello World!\n");
      end  
    with
      // this trail awaits a keypress,
      // then terminates, ending the entire
      // par/or block.
      await KEY;   // awaits KEY input event
    end
    _printf("Bye!\n");
The above code prints "Hello World!" ever second, until a key is pressed, after which it prints "Bye!" before terminating the program.

The reactivity and intuitive single-threaded concurrency makes it a really nice language for low-powered devices. Or robotics, which is a lot about reacting to sensor input.

It has a dedicated Arduino repo too[1].

In practice it's more of a research language by Francisco Sant’Anna, a professor at UERJ, Brazil, than a language with a big community around it. He's currently working on a new version caleld Dynamic Ceu, or dceu[2]

In the same paradigm there is the Blech[3] language, I believe originating from Bosch. Sadly, that project also has lost some steam.

[0] https://github.com/ceu-lang/ceu-arduino

[1] http://ceu-lang.org/

[2] https://github.com/fsantanna/dceu

[3] https://github.com/blech-lang/blech

Re: Coroutines make robot code easy

#53

Thankfully a piece that emphasizes that coroutines are functions that pause. Java frameworks like Quasar became focused on other goals besides that basic capability and lost their way (IMHO). Java's not the easiest to pick up in high school unless you really make a big after-school effort. Something like Lua is probably better.

Unfortunately high schools are forced to continue teaching Java, or else Oracle starts executing hostages.

I feel bad for autonomous participants, Java is almost a uniquely poor choice for the size of project FIRST teams would be creating.

Java has its domains, but small, algorithm driven code worked on by a small, inexperienced group isn't one.

Re: Coroutines make robot code easy

#55

Thankfully a piece that emphasizes that coroutines are functions that pause. Java frameworks like Quasar became focused on other goals besides that basic capability and lost their way (IMHO). Java's not the easiest to pick up in high school unless you really make a big after-school effort. Something like Lua is probably better.

For FIRST robotics in particular, Java and LabView are the most commonly used languages because they are the two for which a robust library is maintained by Worcester Polytechnic Institute for use in the competition. But I have long been of the opinion that both languages are kind of an ill fit for the application. Python is making some headway and I think it might be a better fit; It has some advantages on legibilit…

Thankfully, very few teams are still using LabView at this point and WPILib primarily targets C++ and Java, with first-party Python support coming next season.

Re: Coroutines make robot code easy

#56
Maybe I'm missing something but why doesn't the Java section right before the Lua section not work? It looks like normal procedural code that can just keep running. The lua version is just one coroutine and it's not yielding to anything else. Is it just a matter of some kind of timing constraint/controller from FRC in the background that need to keep calling myAuto?

Re: Coroutines make robot code easy

#57

Yes. The callback is not a natural construct (i.e. it does not map well to our intuitive understanding of X is doing something while Y is doing something else). I'm annoyed when coroutines are reserved for use only in high performance, c10k-type of situations. For example, the KJ library's doc says: "Because of this, fibers should not be used just to make code look nice (C++20's co_await, described below, is a better…

Yes.

What question are you answering 'yes' to?

The callback is not a natural construct

According to who? It is very natural to anyone making a GUI or anything interactive for the firs time. Eventually I would try to move people to queueing up events and handling them all at the same time so that the order is easier to debug.

Coroutines are the latest silver bullet syndrome. Fundamentally you still need to synchronize and order data and that's the hard part. I don't know why students would need to do more than the classic interactive loop of:

1. get data

2. update state

3. interactive output (drawing a frame, moving a robot etc.)

Re: Coroutines make robot code easy

#58

Yes. The callback is not a natural construct (i.e. it does not map well to our intuitive understanding of X is doing something while Y is doing something else). I'm annoyed when coroutines are reserved for use only in high performance, c10k-type of situations. For example, the KJ library's doc says: "Because of this, fibers should not be used just to make code look nice (C++20's co_await, described below, is a better…

>I'm annoyed when coroutines are reserved for use only in high performance,c10k-type of situations

Go's pretty much that idea. Make the threads light as coroutines (I think it's like 4k or 8k per goroutine) and give some basic messaging (channels) to go with it. Works well but some of the simplicity ended up biting it in the arse so there can be quite a bit of boilerplate in some cases.

Re: Coroutines make robot code easy

#59

Maybe I'm missing something but why doesn't the Java section right before the Lua section not work? It looks like normal procedural code that can just keep running. The lua version is just one coroutine and it's not yielding to anything else. Is it just a matter of some kind of timing constraint/controller from FRC in the background that need to keep calling myAuto?

autonomousPeriodic is a tick function; we need to keep ticking. If we spent more than our allotted 20ms in a single autonomousPeriodic then the robot framework’s safety systems kick in and disable all the motors.

Re: Coroutines make robot code easy

#60

Maybe I'm missing something but why doesn't the Java section right before the Lua section not work? It looks like normal procedural code that can just keep running. The lua version is just one coroutine and it's not yielding to anything else. Is it just a matter of some kind of timing constraint/controller from FRC in the background that need to keep calling myAuto?

The robots operate on N ticks per second. You only get one set of robot inputs per tick and can only make one command.

The Java code is tickless. During a single tick none of the while conditions will change.

Therefore the while loop will run forever and never allow the tick to finish.

The Lua code yields at the end of any loop iteration allowing the tick to complete. Then whatever is orchestrating the robot on the next tick calls resume on the coroutine allowing the another iteration to continue, this time with new inputs.

Post reply on HN