Swiftpack.co -  frameworklabs/Synchrosphere as Swift Package
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
frameworklabs/Synchrosphere
A Swift framework to control Sphero robots in a synchronous reactive style.
.package(url: "https://github.com/frameworklabs/Synchrosphere.git", from: "0.1.3")

Synchrosphere

A Swift framework to control Sphero robots in a synchronous reactive style.

About

Sphero robots can be wirelessly controlled and observed from an external computer by sending and receiving Bluetooth messages. Synchrosphere provides an API to do so from a Mac or iOS device in a synchronous reactive manner via the embedded imperative synchronous Swift DSL Pappe. This programming style is especially helpful in robotics as it simplifies the coding of concurrent tasks in a safe manner, due to deterministic synchronization between tasks. This quality also enables sound preemption, which is another important concept in robotics where preconditions needs to be checked and handled constantly.

In addition, this project shows how synchronous reactive programming can help to turn delegate based callback APIs - as common with Apple frameworks - back into structured code to simplify their usage.

Usage

Synchrosphere tries to make it simple to control Sphero robots. Currently only Sphero RVR and Sphero Mini are supported.

Start by importing this package into your project. Its dependency to Pappe will be resolved implicitly.

Next, create a SyncsController in your code and assign it to an instance variable of your App - or some other place which lives long enough.

When creating a SyncsController you provide a configuration of type SyncsControllerConfig and a closure which will build and return the activities to control the robot. One returned activity must be named "Main" and will be called as entry-point once a robot conforming to the configuration was found and activated (see next step). When control returns from this main activity the robot is deactivated again.

Finally, call start() on the created controller to start the scanning, activation and control of the robot. If you want to emergency-stop the robot (or stop a lengthy scanning process ) call stop() any time.

For a usage of the Synchrosphere framework, see also the accompanying project SynchrosphereDemo which provides a UI application to select different robot control demos.

Example

Let's create a Sphero RVR controller which moves the robot in a rectangular loop back to its starting spot while blinking green as long as it moves.

let config = SyncsControllerConfig(deviceSelector: .anyRVR)
ctrl = SyncsEngine().makeController(for: config) { name, ctx in
    activity (name.Main, []) { val in
        cobegin {
            strong {
                run (Syncs.RollForSeconds, [SyncsSpeed(100), SyncsHeading(0), SyncsDir.forward, 3])
                run (Syncs.RollForSeconds, [SyncsSpeed(100), SyncsHeading(90), SyncsDir.forward, 2])
                run (Syncs.RollForSeconds, [SyncsSpeed(100), SyncsHeading(180), SyncsDir.forward, 3])
                run (Syncs.RollForSeconds, [SyncsSpeed(100), SyncsHeading(270), SyncsDir.forward, 2])
            }
            weak {
                `repeat` {
                    run (Syncs.SetMainLED, [SyncsColor.green])
                    run (Syncs.WaitMilliseconds, [500])
                    run (Syncs.SetMainLED, [SyncsColor.black])
                    run (Syncs.WaitMilliseconds, [500])
                }
            }
        }
    }
}

ctrl.start()

The controller is created with a single activity named "Main". The cobegin construct creates two concurrent trails (threads) with the first one responsible for moving the robot and the second one responsible for blinking. The cobegin construct should stop once the first trail has finished (but not earlier) - this is why the first trail is marked strong. The blinking code in the second trail should stop as soon as the move has finished - thus it is marked as weak.

Within the trails, built-in activities to roll the robot, set its LED and wait for some time are called via the run statements. See the header docs for all provided activities and their parameters.

Finally, the controller is started explicitly and runs until it finishes. Note that start() is asynchronous and returns before the robot control code has finished. This is also why the created controller variable ctrl needs to be assigned to a variable with a long enough lifetime (i.e. probably not a local variable).

Limitations

  • Only Sphero RVR and Sphero Mini robots are supported right now.
  • Only a minimal API to control the robots is offered right now.

GitHub

link
Stars: 0
Last commit: 3 days ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Dependencies

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API