Connect the Simplest CPS

In this section we will build the simplest real cyber-physical system!

We will buy a “wink” from Arduino, e.g. make Arduino blink with its onboard led. The lesson is tested on Arduino Uno, but any other board with a led will do the job.

Note

The source code of this lesson is here.

Arduino

The firmware for the board is located in arduino_blink/misc/arduino/arduino.ino. Use Arduino IDE to load the code to your Arduino board.

In the code we subscribe for the /blink_led topic and set a callback. The type of the topic is Empty, so the board waits until someone publishes to the topic and performs the LED blinking.

#include <ros.h>
#include <std_msgs/Empty.h>

ros::NodeHandle  nh;

void blink(int led, int mil) {

  digitalWrite(led, HIGH);
  delay(mil);
  digitalWrite(led, LOW);
  delay(mil);

}

void messageCb( const std_msgs::Empty& toggle_msg){
  blink(LED_BUILTIN, 500);
  blink(LED_BUILTIN, 500);
  blink(LED_BUILTIN, 500);
}

ros::Subscriber<std_msgs::Empty> sub("blink_led", &messageCb );

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  nh.initNode();
  nh.subscribe(sub);
}

void loop()
{
  nh.spinOnce();
  delay(1);
}

AIRA client

Note

You can download the latest release from here

Set up the COM port forwarding as described in this lesson. You should forward your /dev/ttyUSB0 or /dev/ttyACM0 port (depending on the system) to COM1. In the client /dev/ttyS0 will represent the board. After this launch the virtual machine.

ROS

When new liability is created it goes to /liability/ready topic. We have to remember the address and call /liability/start service to get the data from objective.

def newliability(l):
  self.liability = l.address
  rospy.loginfo("Got new liability {}".format(self.liability))

  prefix = "/liability/eth_" + self.liability
  rospy.Subscriber(prefix + '/blink', Empty, self.blink)

  rospy.wait_for_service("/liability/start")
  rospy.ServiceProxy('/liability/start', StartLiability)(StartLiabilityRequest(address=self.liability))
rospy.Subscriber("/liability/ready", Liability, newliability)

A message in the /blink topic come from the objective field. Have a look at Basic usage page.

AIRA

Connect to AIRA client via SSH as described here. You can either upload code from your host OS or make a clone from Github.

To build and launch the ros package run the following commands:

$ nix build -f release.nix
$ . result/setup.zsh
$ rosrun arduino_blink blink.py

Also we need to add a rosbag file to IPFS:

$ ipfs add rosbag/blink.bag

Note

Before the next step you should approve XRT tokens on the Factory.

On your host system build and launch an Dapp for the lesson:

$ git clone https://github.com/airalab/robonomics_tutorials/
$ cd robonomics_tutorials/arduino_blink_dapp
$ npm i && npm run dev

Open the link and press Demand then Offer buttons. Wait until a new liability is created and you should see the board blinking. Congratulations on the first agent!