Difference between revisions of "Tatrabot coordination"

From RoboWiki
Jump to: navigation, search
(Software)
(Software)
 
(21 intermediate revisions by the same user not shown)
Line 6: Line 6:
 
For this project I have used a pair of TATRABOTs. Each bot has a "saddle" that carries the rod and can rotate freely.
 
For this project I have used a pair of TATRABOTs. Each bot has a "saddle" that carries the rod and can rotate freely.
  
[[Image:Tatrabot_coord_1.jpg|300px]][[Image:Tatrabot_coord_2.jpg|300px]][[Image:Tatrabot_coord_3.png|300px]]
+
[[Image:Tatrabot_coord_1.jpg|300px]]       [[Image:Tatrabot_coord_2.jpg|300px]]       [[Image:Tatrabot_coord_3.png|300px]]
  
 
==Software==
 
==Software==
Line 13: Line 13:
 
I have written this in Python 3.5, because of the ease of use of the language.
 
I have written this in Python 3.5, because of the ease of use of the language.
 
The program uses two threads where opens the serial bluetooth connections given by the user, and relays the incoming messages from one thread to another.
 
The program uses two threads where opens the serial bluetooth connections given by the user, and relays the incoming messages from one thread to another.
 +
For the serial connection I have used the pySerial python library, so to compile the relay code you have to download, and install it from pip or [https://pythonhosted.org/pyserial/].
 
<code>
 
<code>
 
     from queue import Queue
 
     from queue import Queue
Line 55: Line 56:
 
</code>
 
</code>
  
Program for the robot. The variable "robotLeft" is used to set on which side is the robot on. (true=left, false=right)
+
Program for the robot. To write and compile the program for the Tatrabots I have used ChibiStudio.
First Start the robots, and then press the 4th button. Now you we can start  the relay what send the start message to each robot.
 
<code>
 
#include "tatrabot.h"
 
#include "demo.h"
 
  
int main(void) {
+
The variable "robotLeft" is used to set on which side is the robot on. (true=left, false=right)
  tatrabotInit();
 
  //robotNavigate();
 
}
 
  
void robotNavigate(void) {
+
First Start the robots, and then press the 4th button.
  int state = 0;
 
  int currentSpeed = 7000;
 
  int motorState = 0;
 
  int robotLeft = false;
 
  motorsOff();
 
  int speedL, speedR;
 
  speedL = speedR = currentSpeed;
 
  countA = countB = 0;
 
  while (!senseButton(4))
 
    ;
 
  chThdSleepMilliseconds(100);
 
  while (!senseButton(3)) {
 
    uint8_t chr = 'x';
 
    sdAsynchronousRead(&SD3, &chr, 1);
 
    switch (chr) {
 
      case 's':
 
        state = 1;
 
        countA = countB = 0;
 
        break;
 
      case '!':
 
        state = 0;
 
        break;
 
      default:
 
        chr = 'x';
 
    }
 
  
    if ((distance > 1300) && (state == 1)) {
+
Now you we can start the relay what send the start message to each robot.
      chSequentialStreamPut(&SD3, '!');
 
      state = 2;
 
    }
 
  
    switch (state) {
+
The code to steer clear of the obstacle:
      case 0:
+
<code>
        motorsOff();
+
            setMotor(3, -currentSpeed);
        break;
+
            chThdSleepMilliseconds(1500);
      case 1:
+
            if (!robotLeft)
        switch (motorState) {
+
              turnLeft(4000, 700);
          case 0:
+
            else
             if (countA > countB + 1) {
+
              turnRight(4000, 700);
               speedR -= 2000;
+
            setMotor(3, -currentSpeed);
               motorState = 1;
+
            chThdSleepMilliseconds(2000);
             }
+
            if (!robotLeft)
             else if (countA < countB - 1) {
+
              turnRight(4000, 700);
               speedL -= 2000;
+
            else
               motorState = 2;
+
              turnLeft(4000, 700);
             }
+
            chSequentialStreamPut(&SD3, 's');
 +
            setMotor(3, currentSpeed);
 +
            chThdSleepMilliseconds(4000);
 +
            chSequentialStreamPut(&SD3, '!');
 +
             if (!robotLeft)
 +
               turnLeft(4000, 700);
 +
            else
 +
               turnRight(4000, 700);
 +
            setMotor(3, currentSpeed);
 +
             chThdSleepMilliseconds(2000);
 +
             if (!robotLeft)
 +
               turnRight(4000, 700);
 +
            else
 +
               turnLeft(4000, 700);
 +
            setMotor(3, currentSpeed);
 +
            chThdSleepMilliseconds(1500);
 +
            state = 1;
 +
             chSequentialStreamPut(&SD3, 's');
 
             break;
 
             break;
          case 1:
+
</code>
            if (countA < countB) {
+
 
              speedR = currentSpeed;
+
==Source code==
              motorState = 0;
+
 
            }
+
The relay code is compiled under Python 3.5, and using the pySerial library.
            break;
+
 
          case 2:
+
You can download pySerial trough pip with the
            if (countA > countB) {
+
<code>pip install pyserial</code>
              speedL = currentSpeed;
+
command, or get it from the [https://pypi.python.org/pypi/pyserial official site] and install it [https://pythonhosted.org/pyserial/pyserial.html#from-source-tar-gz-or-checkout manually].
              motorState = 0;
 
            }
 
            break;
 
        }
 
        setMotor(1, speedL);
 
        setMotor(2, speedR);
 
        break;
 
      case 2:
 
        setMotor(3, -currentSpeed);
 
        chThdSleepMilliseconds(1000);
 
        if (robotLeft)
 
          turnLeft(4000, 700);
 
        else
 
          turnRight(4000, 700);
 
        setMotor(3, -currentSpeed);
 
        chThdSleepMilliseconds(2000);
 
        if (robotLeft)
 
          turnRight(4000, 700);
 
        else
 
          turnLeft(4000, 700);
 
        chSequentialStreamPut(&SD3, 's');
 
        setMotor(3, currentSpeed);
 
        chThdSleepMilliseconds(4000);
 
        chSequentialStreamPut(&SD3, '!');
 
        if (robotLeft)
 
          turnLeft(4000, 700);
 
        else
 
          turnRight(4000, 700);
 
        setMotor(3, currentSpeed);
 
        chThdSleepMilliseconds(2000);
 
        if (robotLeft)
 
          turnRight(4000, 700);
 
        else
 
          turnLeft(4000, 700);
 
        setMotor(3, currentSpeed);
 
        chThdSleepMilliseconds(1000);
 
        state = 1;
 
        chSequentialStreamPut(&SD3, 's');
 
        break;
 
    }
 
  }
 
}
 
  
void turnLeft(int speed, int time) {
+
For the robots you require ChibiStudio Preview 12 and stm32flash for downloading.
  setMotor(1, speed);
+
For tutorial go to [http://dai.fmph.uniba.sk/courses/pphw/tatra_tutorial.html].
  setMotor(2, -speed);
 
  chThdSleepMilliseconds(time);
 
}
 
  
void turnRight(int speed, int time) {
+
Zipped folder containing the [[Media:Project_source_code.zip|project source code]].
  setMotor(1, -speed);
 
  setMotor(2, speed);
 
  chThdSleepMilliseconds(time);
 
}
 
  
</code>
+
==Conclusion==
 +
In the end I have failed to complete the objective fully. The robots didn't behave as I anticipated, because of the precision of the rotation sensors.
 +
Maybe the rod was too heavy for the motors.
  
 
==Video==
 
==Video==
 
+
<youtube>QJ10VSgTXM0</youtube>
==Záver==
 
In the end the robots didn't behave as I anticipated, because of the precision of the rotation sensors.
 

Latest revision as of 15:33, 16 June 2016

Project objective

The goal of my project was to create a program for a pair of TATRABOT robots, such they will be capable to navigate synchronously, while carrying a pole. Another task was to make it, so that the whichever robot detects a obstruction, they will try to navigate around it while trying to not drop the pole.

Hardware

For this project I have used a pair of TATRABOTs. Each bot has a "saddle" that carries the rod and can rotate freely.

Tatrabot coord 1.jpg Tatrabot coord 2.jpg Tatrabot coord 3.png

Software

My project has two components. One is the program that runs on the robot. The another one is a relay, that handles the messaging between the bots, because the bluetooth chip cannot be set to Master mode to connect to another device. So that's why there is a need of a relay.

I have written this in Python 3.5, because of the ease of use of the language. The program uses two threads where opens the serial bluetooth connections given by the user, and relays the incoming messages from one thread to another. For the serial connection I have used the pySerial python library, so to compile the relay code you have to download, and install it from pip or [1].

   from queue import Queue
   from threading import Thread
   from serial import *
   import os
   class Relay(object):
       def __init__(self, ports):
           self.serials = [Serial(port=p, baudrate="57600") for p in ports]
           self.threads = []
           self.alive = False
       def start(self):
           self.alive = True
           self.threads.append(Thread(target=self.transmit,args=(self.serials[0],self.serials[1])))
           self.threads.append(Thread(target=self.transmit, args=(self.serials[1], self.serials[0])))
           for thread in self.threads:
               thread.daemon = True
               thread.start()
       def stop(self):
           self.alive = False
       def join(self):
           for thread in self.threads:
               while thread.isAlive():
                   thread.join(0.1)
       def transmit(self,source, target):
           source.write(bytes([115]))
           while self.alive:
               read = source.read()
               if ord(read) == 112:
                   data = source.read()
                   print("{0}-Print: {1}".format(str(source.port), str(chr(ord(data)))))
               else:
                   if target:
                       target.write(read)
                       print("{0}-Message: {1}".format(str(source.port), str(read)))
                   else:
                       print("{0}-Message: {1}".format(str(source.port), str(read)))
   if __name__ == "__main__":
       relay = Relay(["COM14","COM17"])
       relay.start()
       relay.join()

Program for the robot. To write and compile the program for the Tatrabots I have used ChibiStudio.

The variable "robotLeft" is used to set on which side is the robot on. (true=left, false=right)

First Start the robots, and then press the 4th button.

Now you we can start the relay what send the start message to each robot.

The code to steer clear of the obstacle:

           setMotor(3, -currentSpeed);
           chThdSleepMilliseconds(1500);
           if (!robotLeft)
             turnLeft(4000, 700);
           else
             turnRight(4000, 700);
           setMotor(3, -currentSpeed);
           chThdSleepMilliseconds(2000);
           if (!robotLeft)
             turnRight(4000, 700);
           else
             turnLeft(4000, 700);
           chSequentialStreamPut(&SD3, 's');
           setMotor(3, currentSpeed);
           chThdSleepMilliseconds(4000);
           chSequentialStreamPut(&SD3, '!');
           if (!robotLeft)
             turnLeft(4000, 700);
           else
             turnRight(4000, 700);
           setMotor(3, currentSpeed);
           chThdSleepMilliseconds(2000);
           if (!robotLeft)
             turnRight(4000, 700);
           else
             turnLeft(4000, 700);
           setMotor(3, currentSpeed);
           chThdSleepMilliseconds(1500);
           state = 1;
           chSequentialStreamPut(&SD3, 's');
           break;

Source code

The relay code is compiled under Python 3.5, and using the pySerial library.

You can download pySerial trough pip with the pip install pyserial command, or get it from the official site and install it manually.

For the robots you require ChibiStudio Preview 12 and stm32flash for downloading. For tutorial go to [2].

Zipped folder containing the project source code.

Conclusion

In the end I have failed to complete the objective fully. The robots didn't behave as I anticipated, because of the precision of the rotation sensors. Maybe the rod was too heavy for the motors.

Video