Table of Contents

Kaugjuhitav Spider

Meeskond

Nädalaaruanded

1. Abstract.

This report describes the work done under MHK0020 project rules of spring semester 2011 at TUT(Tallinn University of Technology). “Mechatronics-project” allows the opportunity to try practically the possibilities of our prior education on speciality of mechatronics. Our team was to develop and construct a robot that was to move by control from a remote computer. For this task we were given a Zigbee system which allows control by radio waves. We were to develop mechanic electric and programming parts of our system. With no prior experience in such development our team made our best effort to accomplish given task. We were faced with different challenges. In this report we include our results up to this moment.

2. Sissejuhatus.

Käesolev aruanne kirjeldab kohaselt tehtud töö MHK0020 projekti reeglite kevadsemestril 2001 TTÜ (Tallinna Tehnikaülikool). “Mehhatroonika-projekt” lubab võimaluse proovida peaaegu võimalusi meie eelneva hariduse eriala mehhatroonika. Meie meeskond oli arendada ja ehitada robot, mis oli liikumiseks kontrolli kaugarvutist. Selle ülesanne anti meile Zigbee süsteem, mis võimaldab kontrolli raadiolaineid. Olime arendada mehhaanik elektri-ja programmeerimise osad meie süsteemi. Mis ei ole varasemat kogemust selline areng meie meeskond tegi oma parima, et täita antud ülesanne. Olime silmitsi erinevate probleemidega. Käesolevas raportis me kaasame meie tulemused kuni see hetk.

3. Generalisation.

At the beginning of the project we were given an opportunity to freely choose any robot system to develop with only one limitation: it has to be remotely controlled. We considered our options and decided to try to develop a spider type robot. It seemed that a simple wheel drive would be boring and trivial. So we set our task and searched for the closest analogies on the market. We found a popular model (Picture 1 Market model of a spider robot) and based our concept of it.

spider_robot_2a.jpg

Picture 1 Market model of a spider robot

We pointed out the features that need to be included in our development: * Servo motors * Platform to hold control schemes and motors * Four controlled legs * Two servo motors per leg. * Servo driver to control the motors.

In development of this project these programs were used: * Solid Works- drawing of parts * AutoCAD 2008 - algorithms * Open Office- reports and calculations * Multisim –electronics test

4. Tasks.

We chose to divide our development in to multiple stages and assign each group member his own task to help spread the work load among members with strongest features in each aspect. A four leg system with 2 servomotors were chosen to, ease the burden on the budget of our spider. There were possible hardship with balance, but the risk was taken. We needed the design, the program and the electronics to make the robot hole. That was how we split up the work load. Mihhail Smirnov was assigned the task of making the drawings and figuring out the mechanical aspects. Dmitri Rõsev was responsible for programming and computer communications. Andrei Sorokin was responsible for electronics and gathering. We coordinated our efforts and helped each other in the process. There were several ideas but in the end we filtered out the most effective: * Light materials * Circular algorithm * Several movement possibilities * Zigbee control

During our development we faced several problems: * Possibility of movement * Mechanical connections * USB connection possibilities * Driver programming and output numbers * Slow response

5. Time schedules.

Week Plan Done
1 Choosing the project and group assignment Assigned to the group and given the task
2 Idea analysis and planning Ideas were thought through and decided on a concept and how it would function
3 Programming Programs and algorithms
4 Electronics planning and one leg development Driver scheme and ZigBee system were implemented
5 Electronics gathering New driver was suggested
6 Drawing and parts making. Drawing were maid but it was not possible to make parts.
7 Gathering Driver to servo development and tuning
8 Document finishing Documents were finished

6.Development.

6.1. Electronics

08307627979975.jpg

Picture 2 Block diagram

6.2. Spider concept and parts.

08214077581ce3.jpg

Picture 3 Spider concept

We started of with a concept of our spider (Picture 2 Spider concept) robot and from there decided on part placement and there characteristics. It was decided that we stick to the basics and try not to over complicate our robot. Since we decided on the components it was a mater of time to pick them out by price and characteristics.

1) SSC-32

This is the best servo controller value available. 32 channels of 1uS resolution servo control. Bidirectional communication with Query commands. Synchronized, or “Group” moves. 12 Servo Hexapod Gait Sequencer built in.

2) XBee-PRO

The XBee-PRO 802.15.4 (formerly Series 1) OEM RF module is an IEEE 802.15.4 compliant solution that satisfies the unique needs of low-cost, low-power wireless sensor networks. The module is easy-to-use, requires minimal power and provides reliable delivery of critical data between devices. Innovations stamped in the XBee-PRO design enable it to yield two- to three-times the range of standard ZigBee modules. The XBee-PRO 802.15.4 module operates within the ISM 2.4 GHz frequency band and is pin-for-pin compatible with Digi's regular XBee (1 mW) 802.15.4 module. The modules are optimised for use in US, Canada, Australia, Israel and Europe. No configuration is necessary for out-of-box RF communications. The module’s default configuration supports a wide range of data system applications. Advanced configurations can be implemented using simple AT commands.

Product summary:

3) DCServo S03NF STD

Product Information S/TEC STD S03NF/2BB/MG (S07/2BB) SERVO - 7720340

To summaries here is a price list with the total of the components used:

Component Number Name Price
Servomotor 8 DCServo s30NF STD $160
Xbee-PRO 2 Xbee-PRO module $64
Servo driver 1 SSC-32 $39.95
Total $263.95

6.3. Algorithm and programming.

0825392675dc5c.jpg

Picture 4 Movement Algorithm

Movement algorithm (Picture 3 Movement Algorithm) description: At first the system is implemented with the program and a check of status is accomplished (d0). All components are set to default positions and are now ready to work. Default position is considered as position of the leg when its joint part is perpendicular to the surface and its base leg part is parallel to the short side of the base.

Step 1 (c0): A movement command is issued and the controller is choosing the appropriate action according to the program implemented:

Sideways movement is not implemented in to our system but is possible with use from more than 2 servo motors per leg. That possibility can be used in the later models of our system. This application (c3) will not be mentioned further.

Step 2.1 (c1): There are two possibilities of direct movement:

Front movement (a1) function in the program moves the joint servo of the first leg(front right from the upper perspective) by 45 degrees clockwise (from the front perspective) then the base servo 45 degrees counter-clockwise (from the upper perspective). Joint servo is returned to its default position, then base servo to its default position. Other legs move to the same pattern with given time periods. Back movement (a2) function in the program moves the joint servo of the first leg(front right from the upper perspective) by 45 degrees clockwise (from the front perspective) then the base servo 45 degrees clockwise (from the upper perspective). Joint servo is returned to its default position, then base servo to its default position. Other legs move to the same pattern with given time periods.

Step 2.2 (c2): There are two possibilities of turn movement:

Left movement (a3) function in the program moves the joint servo of the first leg(front right from the upper perspective) by 45 degrees clockwise (from the front perspective) then the base servo 45 degrees clockwise (from the upper perspective). Joint servo is returned to its default position, then base servo to its default position. The legs connected by a side move there base servo in opposite direction by 45 degree with given time period. Right movement (a4) function in the program moves the joint servo of the first leg(front right from the upper perspective) by 45 degrees clockwise (from the front perspective) then the base servo 45 degrees counter-clockwise (from the upper perspective). Joint servo is returned to its default position, then base servo to its default position. The legs connected by a side move there base servo in opposite direction by 45 degree with given time period.

Step 3: System controls if the movement is repeated or stopped (d1) and if the movement is repeated then a loop goes to check what movement pattern is selected. It is possible to continue the chosen movement or to select a different pattern.

Addition: If the algorithm reaches the “End” point the joint and the base servos are returned to the default position.

meh_proekt_pc_prog.jpg

Picture 5 Menu control of a robot.

1) Shows all ports that have any devices connected to them.

2) These buttons make robot to move forward, turn left or right and to stop the current command and take standart position

3) These buttons controls the movements of a single leg of the robot

Source for the microcontroller:

#include <homelab/usart.h>
#include <homelab/delay.h>
#include <string.h>
#include <stdio.h>
 
//	COM connector
usart in_port = USART(0);
 
//	pinhead GND/RX/TX
usart out_port = USART(1);
 
int main(void)
{
	unsigned char i;
	char c;
	int str[40];
	int inc=50;
	int init_pos[]={600, 1100, 2000, 1300, 2200, 1300, 100, 1300};
	int pos[sizeof(init_pos)/sizeof(int)];
	for(i=0; i<sizeof(init_pos)/sizeof(int); i++){
		pos[i]=init_pos[i];
	}
 
	//	USART 
	usart_init_async(in_port,
		USART_DATABITS_8,
		USART_STOPBITS_ONE,
		USART_PARITY_NONE,
		USART_BAUDRATE_ASYNC(9600));
 
	//	TX RX
	usart_init_async(out_port,
		USART_DATABITS_8,
		USART_STOPBITS_ONE,
		USART_PARITY_NONE,
		USART_BAUDRATE_ASYNC(115200));
 
	//	Loop
	while (true)
	{
		usart_try_read_char(in_port, &c);
		if(c=='f'){
			//	Initial positionв
			usart_send_string(out_port, 
			"#0 P600 #3 P1100 #12 P1300 #15 P1150 #16 P2000 #19 P1300 #28 P1300 #31 P1850 \r");
			for(i=0; i<sizeof(pos)/sizeof(int); i++){
				pos[i]=init_pos[i];
			}
		}
		//	Left upper leg
		else if(c=='a'){
			/*
				Left bottom leg
			*/
			usart_send_string(out_port, "#15 P1200\r");
			hw_delay_ms(300);
			usart_send_string(out_port, "#12 P900\r");
			hw_delay_ms(300);
			usart_send_string(out_port, "#15 P1100\r");
			hw_delay_ms(300);
			/*
				Right bottom leg
			*/
			usart_send_string(out_port, "#31 P1750\r");
			hw_delay_ms(300);
			usart_send_string(out_port, "#28 P1800\r");
			hw_delay_ms(300);
			usart_send_string(out_port, "#31 P1850\r");
			hw_delay_ms(300);
			/*
				Right upper leg
			*/
			usart_send_string(out_port, "#16 P1950\r");
			hw_delay_ms(300);
			usart_send_string(out_port, "#19 P1100\r");
			hw_delay_ms(300);
			usart_send_string(out_port, "#16 P2050\r");
			hw_delay_ms(300);
			/*
				Left upper leg
			*/
			usart_send_string(out_port, "#0 P750\r");
			hw_delay_ms(300);
			usart_send_string(out_port, "#3 P1200\r");
			hw_delay_ms(300);
			usart_send_string(out_port, "#0 P550\r");
			hw_delay_ms(300);
// 
			usart_send_string(out_port, "#12 P1100 #28 P1600 #19 P900 #3 P1400 T500\r");
			hw_delay_ms(1000);
		}
		else if(c=='q'){
			pos[0]+=inc;
			sprintf(str, "#0 P%i \r", pos[0]);
			usart_send_string(out_port, str);
		}
		else if(c=='w'){
			pos[0]-=inc;
			sprintf(str, "#0 P%i \r", pos[0]);
			usart_send_string(out_port, str);
		}
		else if(c=='e'){
			pos[1]-=inc;
			sprintf(str, "#3 P%i \r", pos[1]);
			usart_send_string(out_port, str);
		}
		else if(c=='r'){
			pos[1]+=inc;
			sprintf(str, "#3 P%i \r", pos[1]);
			usart_send_string(out_port, str);
		}
 
		//	Right upper leg
		else if(c=='t'){
			pos[2]-=inc;
			sprintf(str, "#16 P%i \r", pos[2]);
			usart_send_string(out_port, str);
		}
		else if(c=='y'){
			pos[2]+=inc;
			sprintf(str, "#16 P%i \r", pos[2]);
			usart_send_string(out_port, str);
		}
		else if(c=='u'){
			pos[3]+=inc;
			sprintf(str, "#19 P%i \r", pos[3]);
			usart_send_string(out_port, str);
		}
		else if(c=='i'){
			pos[3]-=inc;
			sprintf(str, "#19 P%i \r", pos[3]);
			usart_send_string(out_port, str);
		}
 
		//	Left bottom leg
		else if(c=='o'){
			pos[4]-=inc;
			sprintf(str, "#31 P%i \r", pos[4]);
			usart_send_string(out_port, str);
		}
		else if(c=='p'){
			pos[4]+=inc;
			sprintf(str, "#31 P%i \r", pos[4]);
			usart_send_string(out_port, str);
		}
		else if(c=='['){
			pos[5]+=inc;
			sprintf(str, "#28 P%i \r", pos[5]);
			usart_send_string(out_port, str);
		}
		else if(c==']'){
			pos[5]-=inc;
			sprintf(str, "#28 P%i \r", pos[5]);
			usart_send_string(out_port, str);
		}
 
		//	Right bottom leg
		else if(c=='g'){
			pos[6]+=inc;
			sprintf(str, "#15 P%i \r", pos[6]);
			usart_send_string(out_port, str);
		}
		else if(c=='h'){
			pos[6]-=inc;
			sprintf(str, "#15 P%i \r", pos[6]);
			usart_send_string(out_port, str);
		}
		else if(c=='j'){
			pos[7]-=inc;
			sprintf(str, "#12 P%i \r", pos[7]);
			usart_send_string(out_port, str);
		}
		else if(c=='k'){
			pos[7]+=inc;
			sprintf(str, "#12 P%i \r", pos[7]);
			usart_send_string(out_port, str);
			c='.';
		}
	}
}

The source for personal computer:

#include <QtGui/QApplication>
#include "mainwindow.h"
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
//    w.setFixedSize(650, 380);
    w.show();
 
    return a.exec();
}
#include "mainwindow.h"
#include <rs232/rs232.c>
#include <stdio.h>
#include <iostream>
#include <string>
 
MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent)
{
    h_layout_ports=new QHBoxLayout;
    h_layout_buttons=new QHBoxLayout;
    g_layout=new QGridLayout;
    textEdit_log=new QTextEdit;
 
    //  Commands: legs
    list_char_commands_legs
            << 'q' << 'w' << 'e' << 'r' //  Left upper leg
            << 't' << 'y' << 'u' << 'i' //  Right upper leg
            << 'o' << 'p' << '[' << ']' //  Left bottom leg
            << 'g' << 'h' << 'j' << 'k'; // Right bottom leg
 
    //  Commands: movements
    list_char_commands_movements
            << 'a'  //  Move forward
            << 's'  //  Tern left
            << 'd' //   Tern right
            << 'f'; //  Stop
 
    // Labels: legs
    list_label_legs.append(new QLabel("Left upper leg"));
    list_label_legs.append(new QLabel("Right upper leg"));
    list_label_legs.append(new QLabel("Right bottom leg"));
    list_label_legs.append(new QLabel("Left bottom leg"));
 
    //  Buttons: legs
    for(int i=0; i<4; i++){
        list_button_legs.append(new QPushButton("Up"));
        list_button_legs.append(new QPushButton("Down"));
        list_button_legs.append(new QPushButton("Forward"));
        list_button_legs.append(new QPushButton("Backward"));
    }
 
    //  Buttons: movements
    list_button_movements.append(new QPushButton("Move\nForward"));
    list_button_movements.append(new QPushButton("Turn\nLeft"));
    list_button_movements.append(new QPushButton("Turn\nRight"));
    list_button_movements.append(new QPushButton("Stop"));
 
    //  Horizontal layout: movements' buttons
    //  Fixed size: movements' buttons
    //  Connection: movements' buttons and movement_buttons_push()
    for(int i=0; i<list_button_movements.size(); i++){
        h_layout_buttons->addWidget(list_button_movements.at(i));
        list_button_movements.at(i)->setFixedSize(100, 50);
        connect(list_button_movements.at(i), SIGNAL(pressed()), this, SLOT(movement_buttons_push()));
    }
 
    // Connection: legs' buttons and legs_buttons_push()
    for(int i=0; i<list_button_legs.size(); i++){
        connect(list_button_legs.at(i), SIGNAL(pressed()), this, SLOT(legs_buttons_push()));
    }
 
    //  Horizontal layouts: legs' buttons
    for(int i=0; i<4; i++){
        list_hLayout_buttons.append(new QHBoxLayout);
        for(int k=i*4; k<4*i+4; k++){
            list_hLayout_buttons.at(i)->addWidget(list_button_legs.at(k));
        }
    }
 
    //  Open serial ports
    //  Horizontal layoyt: ports
    int usb_ports=16;
    for(int i=0; i<4; i++){
        if(OpenComport(usb_ports, 9600)==0){
            QString str;
            str.sprintf("Port %i", i);
            list_radio_button_ports.append(new QRadioButton(str));
            h_layout_ports->addWidget(list_radio_button_ports.at(i));
            usb_ports++;
        }
        else break;
    }
 
    //  Grid layout
    g_layout->addLayout(h_layout_ports, 0, 0);
    g_layout->addLayout(h_layout_buttons, 1, 0);
    for(int i=0; i<list_hLayout_buttons.size(); i++){
        g_layout->addWidget(list_label_legs.at(i), (i+2)*2, 0);
        g_layout->addLayout(list_hLayout_buttons.at(i), (i+2)*2+1, 0);
    }
    g_layout->addWidget(textEdit_log, 12, 0);
 
    //  Set layout of main window
    setLayout(g_layout);
}
 
MainWindow::~MainWindow()
{
 
}
void MainWindow::legs_buttons_push(){
    for(int i=0; i<list_button_legs.size(); i++){
        if(list_button_legs.at(i)->isDown()){
            for(int k=0; k<list_radio_button_ports.size(); k++){
                if(list_radio_button_ports.at(k)->isChecked()){
                    SendByte(16+k, list_char_commands_legs.at(i));
                }
            }
        }
        else{
            for(int k=0; k<list_radio_button_ports.size(); k++){
                if(list_radio_button_ports.at(k)->isChecked()){
                    SendByte(16+k, '.');
                }
            }
        }
    }
}
void MainWindow::movement_buttons_push(){
    for(int i=0; i<list_button_movements.size(); i++){
        if(list_button_movements.at(i)->isDown()){
            for(int k=0; k<list_radio_button_ports.size(); k++){
                if(list_radio_button_ports.at(k)->isChecked()){
                    SendByte(16+k, list_char_commands_movements.at(i));
                }
            }
        }
    }
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QtGui>
 
class MainWindow : public QWidget
{
    Q_OBJECT
 
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
public slots:
    void movement_buttons_push();
    void legs_buttons_push();
private:
    QGridLayout *g_layout;
    QHBoxLayout *h_layout_ports, *h_layout_buttons;
    QList<QRadioButton *> list_radio_button_ports;
    QList<QLabel *> list_label_legs;
    QList<QPushButton *> list_button_legs;
    QList<QPushButton *> list_button_movements;
    QList<QHBoxLayout *> list_hLayout_buttons;
    QList<char> list_char_commands_legs, list_char_commands_movements;
    QTextEdit *textEdit_log;
};
 
#endif // MAINWINDOW_H

6.4. Construction.

During the last part of the development we were given access to tools to make parts for our robot. At first we decided it would be best to make the robot out of aluminium for its good characteristics, but after we tried to make the first leg it was decided that plastic would suit best with its lighter possibilities for remodelling and sculpting. The Picture 4 Spider leg shows a built leg of our robot. The horizontal part is referred to as “base part” the second half of the leg is referred to as “joint part”. In both joint and base part a holes of 2,5 mm were made for attachment of servo motors. In the base part is also a cut was made to fit and attach a servo motor. A similar cut were made in the platform to fit the four servos that move the base parts. There are four 3mm holes that attach the servo motor in its place on the base and on the platform. The platform is fit with 4 holes of 4mm on the axes to hold an upper platform for controller and driver mounting.

083076275dfe38.jpg 0830762777f11d.jpg

Picture 6 Detail drawings

0825386775fd16.jpg

Picture 7 Spider leg

08303862927a00.jpg 08303863122f24.jpg

Picture 8 Assembled spider

7. Other spiders on the market.

We are including a series of similar robots on the market with there characteristics and costs to show the possible improvements of our model against the competitors.

1. Small Spider Robot

graz-outdoor-small.jpg

Price: Unknown

2. Lynxmotion BH3-R robotic spider

bh3r02.jpg

The body is 18 inches wide and made of custom cut Lexan panels. The servo brackets are aluminium. The Lynxmotion BH3-R hexapod uses 18 servos to manoeuvre its six legs (each with three degrees of freedom) at up to a foot per second in any direction and can clear objects 4 inches high. Price: $750

3. Joinmax Digital Quadruped Robot Kit

4ft001abig.jpg

8 servos. With all mechanical components, a 16-servo controller, PC software, and a download cable included, this walking robot kit is very complete: the only thing you need to add is five standard, AA size batteries. NiMH cells are recommended because of the high current consumption of the robot. Price: $230.

8. Conclusions.

During the development we faced many unexpected problems. Especially nearing the dead line we came across some trouble with the drivers, but we managed to make ends meat. We now know what it is to be involved in a full scale design and build of a mechatronics project with its troubleshoots and unexpected and some times not so obvious solutions. We are sure that this experience will benefit our skills as engineers and developers. It took all our combined powers to make this project work and it was thanks to our prior education in TUT and a lot of help from our supervisor Raivo Sell PhD.

9. Used literature.

  1. http://home.roboticlab.eu/ (3/18/2011 5:06 PM)
  2. http://auto.howstuffworks.com/ (3/18/2011 5:39 PM)