C.R.A.P. (Controlled Rapiro Analog Project)

Who are we?

Dan Hansen, Karsten Darré og Mads Kristensen

Quest: To make a Rapiro robot move with input from an analog controller.

We started working with the Rapiro robot and found out that the Rapiro uses an Arduino board as its mainboard. The movement code can be found on their gitHub and then can be uploaded via USB to the mainboard.

Now we could send movement commands via our PC and needed to figure out how to do it from our Raspberry Pi. We had a lot of troubles with this because the internet only provided information on how to connect with python 2.7, and we were coding in python 3.

At first we thought that we could wire the Rapiro to our Pi’s pins, but this didn’t seem to work. We then came up with the idea to use serial messaging because we knew that it worked based on the experience from the computer.

Here you can see the code for the basic serial connection from the Pi’s USB port to the Rapiro mainboard:

import serial
import smbus

bus = smbus.SMBus(1)

ser=serial.Serial('/dev/ttyUSB0', 57600)

ser.write("$M0".encode('utf-8))

Now that we could send movement messages from our Pi we wanted to implement an analog controller for increasing the usability. We had some code from an earlier project with an analog controller which we combined with our serial connection.

Here you can see how it is combined:

import serial
import smbus
import time

bus = smbus.SMBus(1)

ser=serial.Serial('/dev/ttyUSB0', 57600)

while True:
    time.sleep(0.1)
    # Read analog - X-Akse
    bus.write_byte(0x48, 0x00)
    falseReadX = bus.read_byte(0x48)
    readingX = bus.read_byte(0x48)
    
    if (readingX > 130):
        ser.write("$M4".encode('utf-8'))
        # print data
        print("Højre")
    if (readingX < 100):
        ser.write("$M3".encode('utf-8'))
        # print data
        print("Venstre")

    # read analog - Y-Akse
    bus.write_byte(0x48, 0x01)
    falseReadY = bus.read_byte(0x48)
    readingY = bus.read_byte(0x48)
    
    if (readingY > 130):
        ser.write("$M2".encode('utf-8'))
        # print data
        print("Tilbage")
    if (readingY < 100):
        ser.write("$M1".encode('utf-8'))
        # print data
        print("Frem")

    # read analog - Knap
    bus.write_byte(0x48, 0x02)
    falseReadKnap = bus.read_byte(0x48)
    readingKnap = bus.read_byte(0x48)
    # if else if knap
    if (readingKnap > 230):
        ser.write("$M6".encode('utf-8'))
        # print data
        print("function")
    
    if (readingY < 130 and readingY > 100 and readingX < 130 and readingX > 100):
       ser.write("$M0".encode('utf-8'))

 

When this was working we thought i would be funny to make wireless controls instead. We divided the code in two parts – A sender and a reciever. We used UDP for this solution because it’s fast and easy.

Sender:

import smbus
import time
import socket

bus = smbus.SMBus(1)

remote_ip = "192.168.3.14" #Robot IP

UDP_IP = "192.168.3.205" #Sender IP
UDP_PORT = 5005


suck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)



while True:
    time.sleep(0.1)
    # Read analog - X-Akse
    bus.write_byte(0x48, 0x00)
    falseReadX = bus.read_byte(0x48)
    readingX = bus.read_byte(0x48)
    # if else if for readingX
    if (readingX > 130):
        suck.sendto(bytes(str("readingX,150"),'utf-8'),(remote_ip, UDP_PORT))
        # print data
        print("Højre")
    if (readingX < 100):
        suck.sendto(bytes(str("readingX,50"),'utf-8'),(remote_ip, UDP_PORT))
        # print data
        print("Venstre")
   
    # read analog - Y-Akse
    bus.write_byte(0x48, 0x01)
    falseReadY = bus.read_byte(0x48)
    readingY = bus.read_byte(0x48)
    # if else if for readingY
    if (readingY > 130):
        suck.sendto(bytes(str("readingY,150"),'utf-8'),(remote_ip, UDP_PORT))
        # print data
        print("Tilbage")
    if (readingY < 100):
        suck.sendto(bytes(str("readingY,50"),'utf-8'),(remote_ip, UDP_PORT))
        # print data
        print("Frem")

    # read analog - Knap
    bus.write_byte(0x48, 0x02)
    falseReadKnap = bus.read_byte(0x48)
    readingKnap = bus.read_byte(0x48)
    # if else if knap
    if (readingKnap > 230):
        suck.sendto(bytes(str("button,250"),'utf-8'),(remote_ip, UDP_PORT))
        # print data
        print("function")

    if (readingY < 130 and readingY > 100 and readingX < 130 and readingX > 100 and readingKnap < 200):
        suck.sendto(bytes(str("STOP"),'utf-8'),(remote_ip, UDP_PORT))

 

Reciever:

import serial
import socket
import time

ser=serial.Serial('/dev/ttyUSB0', 57600)


UDP_PORT = 5005

suck = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
suck.bind(("192.168.3.14",UDP_PORT))

while True:
   data, addr = suck.recvfrom(1024)
   data = data.decode('utf-8')
   
   #Analog X
   if data.startswith("readingX"):
      readX = data.split(",")
      if int(readX[1]) > 130:
         #Turn Right
         ser.write("$M4".encode('utf-8'))
      if int(readX[1]) < 100:
         #Turn Left
         ser.write("$M3".encode('utf-8'))
   #Analog Y
   if data.startswith("readingY"):
      readY = data.split(",")
      if int(readY[1]) > 130:
         #Go back
         ser.write("$M2".encode('utf-8'))
      if int(readY[1]) < 100:
         ser.write("$M1".encode('utf-8'))

   #Button
   if data.startswith("button"):
      readB = data.split(",")
      if int(readB[1]) > 230:
         #Wave
         ser.write("$M6".encode('utf-8'))

   #Stand still
   if data.startswith("STOP"):
      ser.write("$M0".encode('utf-8'))
      print(data)

#RobotDads