sábado, 30 de marzo de 2013

Cheapest robotic platform: Smart car

[Updated 12/12/2013:
The commented kit is not being sold currently at dx, but it's sold at Hobby King ]

There are also others kits like:

Funduino Tracking Maze Car for Arduino

Smart Car Chassis Kit for Arduino
]

I have bought the most affordable robotics platform (some photos here) I have found around Internet (at DX): 38€/49$ for all this components:

Ultrasonic Smart Car Kit

My construction:

[caption id="" align="alignnone" width="445"]Cheapest robotic platform Cheapest robotic platform[/caption]

It's really cheap, all the components work flawlessly and very well but IT DOES NOT INCLUDE ANY DOCUMENTATION and some parts (pan tilt base) are impossible to ensemble (it needs another micro servo, 3€/4$) and there is no way to mount on the robot base. Even that, I Think is a good deal, but you should work to get all the needed information (yes, all needed information is over Internet) and put your imagination to build it. I have used Lego Technics parts to mount the ultrasonic sensor.

Here is all the info I have found for every electronic part, code examples and, of course, (soon) a video.

lunes, 25 de marzo de 2013

So... let's the Bioloid, C++ and QT games start!

To cretate this workshop I'm using Ubuntu 12.04, GNU g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 (see Synaptic installer capture),

[caption id="attachment_1635" align="aligncenter" width="300"]Synaptic G++ Synaptic G++[/caption]

QT 5.0.1 and QT creator 2.6.2,

QT creator is a very easy, and good, free IDE with a great design tool for creating user interfaces:

Be careful with this bug: Qt Creator 2.0: UI layout is not updated before launching the application http://qt-project.org/forums/viewthread/292 Is very annoying and time consuming, the solution is in the last comment (setting the UI_DIR in the .pro file)

[caption id="attachment_1637" align="aligncenter" width="600"]QTCreator Bioloid QTWorkshop QTCreator Bioloid QTWorkshop[/caption]

I also will use it with Windows 7.

I also use Boost to get some C++11 features for threading. For example:

pWorkThread = new thread(&Activity::doWork, this, parameter);

std::lock_guard < std::mutex > guard(myMutex);

Don't bother if you don't understand it right now, it's in the guts of the AXControl_v2 library we will use it in a very easy way, as you will see below. Here you will find a lot of resources to learn basic and advanced C++

Example context fot std::lock_guard < std::mutex > guard(myMutex);

[sourcecode language="cpp"]

short DynamixelCommunication::readSensorValue(int id, AX12Address address,
int port) {
std::lock_guard < std::mutex > guard(myMutex);
short value = -1;
try {
int size = getReadSensorWordCommand(buffer, (byte) (id), address,
(byte) (port));
memset(&result, 0, MaxBufferSize);
serialPort.query(buffer, result, size, WaitTimeReadSensor);
value = getQueryResult(result, size);
if (value <= 0)
Debug::show("DynamixelCommunication.readSensorValue", value);

} catch (exception e) {
Debug::show("DynamixelCommunication.readSensorValue", e.what());
}
return value;
}

[/sourcecode]

And context for pWorkThread = new thread(&Activity::doWork, this, parameter);:

[sourcecode language="cpp"]

class Activity {
private:

protected:
std::thread *pWorkThread;

...

}

void Activity::start(int parameter) {
working = true;
pWorkThread = new thread(&Activity::doWork, this, parameter);
Util::sleepMS(10);
}
Let's see how to open the connection
[/sourcecode]

Let's see how to open the connection to the CM-510:

[sourcecode language="cpp"]
void MainWindow::on_B_Open_clicked()
{
//QString output="Open it";
//QMessageBox::information(this, "Output", output, QMessageBox::Ok);

//dynComm.open("/dev/ttyUSB0",57600); //open with these parameters
if (pDynComm->open()) //open getting the parameter from the configuration fiel
{
//Connection opened
setConnectionButtons(true); //User interface update
updateAX12Parameters(ui->SB_AX12_1_ID->text().toInt()); //User interface update
}
else
{
//Show problem opening the connection
string cantOpenPortName="I can't open port: ";
cantOpenPortName+=pConf->getStringValue(DynamixelCommunication::ParameterSerialPortName);

QMessageBox::information(this, "Error", QString::fromStdString(cantOpenPortName), QMessageBox::Ok);
}
}
[/sourcecode]

and get a beep from the Robotis CM-510 (using this alternative firmware):

[sourcecode language="cpp"]
pDynComm->sendOrder(200, MyCommunications::BeepCM510, 0); //200 is the Dynamixel device ID used for the CM-510, 0 because beep doesn't need any additional value
[/sourcecode]

Getting the AX12 position and showing it:

[sourcecode language="cpp"]
void MainWindow::on_B_AX12_1_GET_POS_clicked()
{
QString qStr;

int id = getAX12_1_Id();

int position = pDynComm->readValue(id, MyCommunications::PresentPosition);

ui->SB_AX12_1_POS->setValue(position);
[/sourcecode]

Setting the AX12 position:

[sourcecode language="cpp"]
void MainWindow::on_B_AX12_1_SET_POS_clicked()
{
int id = getAX12_1_Id();

int position= ui->SB_AX12_1_POS->text().toInt();
pDynComm->sendOrder(id, MyCommunications::GoalPosition,position);
}
[/sourcecode]

Putting the selected AX12 LED on and off

[sourcecode language="cpp"]
void MainWindow::on_CH_AX12_1_LED_clicked(bool checked)
{
int id = getAX12_1_Id();

pDynComm->sendOrder(id, MyCommunications::LED, (checked?1:0));// if checked 1, else 0
}
[/sourcecode]

And an auxiliary UI method to get the id from the selected AX-12

[sourcecode language="cpp"]
{
int MainWindow::getAX12_1_Id()
{
QString qStr=ui->SB_AX12_1_ID->text();
int id=Util::convertToInt(qStr.toStdString());

return id;
}
[/sourcecode]

You can download sources and Linux binaries here

A diagram with all the AXControl_v2 lib classes and their methods:

[caption id="attachment_1384" align="aligncenter" width="600"]c++ signatura c++ signatura[/caption]

[Update]

[caption id="attachment_1722" align="aligncenter" width="164"]QT5 Bioloid Workbench QT5 Bioloid Workbench[/caption]

domingo, 17 de marzo de 2013

C++, Bioloid and Raspberry Pi (v0.2)

[V.02 updates: AX C++ architecture, core classes diagram and HexaWheels scanning video]

Why C++, Bioloid and Raspberry Pi?


[caption id="attachment_1254" align="alignleft" width="150"]C++ Stroustrup's book C++ Stroustrup's book[/caption]

C++, specially with the great improvements of the last C++11 standard, joins together a great efficiency in performance and a low memory footprint with advanced high level language features, making C++ a great tool for embedding, robotics, programming.

If you want to know how to use C++ very efficiently these two guides will help you:

- The JSF air vehicle C++ coding standards ( F-35 fighter aircraft)

- ISO C++ committee's report on performance

.

.

 

[caption id="attachment_1221" align="alignleft" width="300"]Bioloid Premium Bioloid Premium[/caption]

Bioloid Premium is a wonderful kit for creating legged and wheeled robots, including (here full parts list):

- 18 powerful and versatile AX-12 servos

- an ATMega 2561 (CM-510) or, recently, an ARM STM32F103RE 32bits (CM-530), based controller. Also you can control the AX-12 with the USB2Dynamixel straight from your USB with a FTDI driver.

- And a lot of parts to create the structure of the robot

.

[caption id="attachment_1257" align="alignleft" width="216"]RaspberryPi RaspberryPi[/caption]

Raspberry Pi is the cheaper and more brilliant conceived SBC (more specifications here):

- Broadcom BCM2835 SoC full HD multimedia applications processor

- 700 MHz Low Power ARM1176JZ-F Applications Processor

- Dual Core VideoCore IV® Multimedia Co-Processor

- 256/512 MB SDRAM

One simple example:
[youtube http://www.youtube.com/watch?v=Yhv43H5Omfc&w=480&h=360]

Learning C++



Starting:

C++ is a very powerful but complex programming language, so I think that the better approach is to start step by step, from the most easy features (yes, C++ could be used in an easy way) to the most advanced features it offers. What is C++? I will quote (I try to not explain anything that already is explained), Stroustrup, "his father", from his book The C++ programming language 3th Edition:
"C++ is a general-purpose programming language with a bias towards systems programming that
– is a better C,
– supports data abstraction,
– supports object-oriented programming, and
– supports generic programming."

And wikipedia:
C++ (pronounced "see plus plus") is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features.[3] Developed by Bjarne Stroustrup starting in 1979 at Bell Labs, it adds object oriented features, such as classes, and other enhancements to the C programming language.

Web resources:

If you want more C++ links, these found at JUCE will help you.




[caption id="attachment_1385" align="alignright" width="140"]Programming -- Principles and Practice Using C++Programming -- Principles and Practice Using C++ Programming -- Principles and Practice Using C++[/caption]

Free books and documents:




- Maintain stability and compatibility with C++98 and possibly with C;
- Improve C++ to facilitate systems and library design, rather than to introduce new features useful only to specific applications;
- Increase type safety by providing safer alternatives to earlier unsafe techniques;
- Increase performance and the ability to work directly with hardware


Books:

Advancing:

In robotics, and embedded programming in general, we will need some advanced knowledge and practices to reach our goals.

Free books and documents:


  • Concurrent programming, threading Our robots we will need to do several actions simultaneously, like perceiving the world with several sensors, moving and deciding what to do to reach is objectives.



  • Communications, the serial port communications functions are used for wireless and wired connections, and we will need to communicate between controllers and with sensors and servos.


Books:

C++ robotics programming


Well, this is really the goal, robotics programming.

As this is a workshop it will follow the creation of the the walker and vehicle Hexapod showed above in the video. This is currently the core architecture and the HexaWheels module (namespace classes):

[caption id="attachment_1391" align="aligncenter" width="300"]AX C++ architecture v2 AX C++ architecture v2[/caption]

And these are the core classes:

todo_signatura

The workshop will include:

- Basics

Like communications with serial port and wireless, using Dynamixels, sensors, ... Language features for robotics, like asynchronous communications and threads and... delays!.

- Intermediate

Combination of basics features using sensors (like scanning) and servos (walking motions). For example, scanning with a DMS sensor:

As a simple example:

[youtube http://www.youtube.com/watch?v=UHKaYuaZi4A&w=480&h=360]

- Advanced

Advanced perception and behaviours

I think this could very funny, using an advanced sensor like Asus Xtion, to detect certain objects to interact, and create configurable and amusing behaviours.

CM-510 mirocontroller programming

- Tools:

PC, Raspberry Pi and Pandaboard, installation and configuration, tool and projects

- GNU C++, Boost
- Eclipse
- QT 5

The contents will come soon, very soon...

C. C++, C# robotics programming Workshop/tutorial with the cheapest robotic platform

[caption id="" align="alignleft" width="108"]My Smart Car construction My Smart Car construction[/caption]

[Update March 30, 2013: Added photo gallery]

I will start a C. C++, C# robotics programming Workshop/tutorial with the cheapest robotic platform I have found at dealextreme.com: (Arduino based) plus a Raspberry Pi (like this that use Bioloid as the hardware platform):

Ultrasonic Smart Car Kit

I have not still received the kit, but I will review the kit and start the workshop as soon as I receive it.

miércoles, 13 de marzo de 2013

Playing With Qt 5, C++ and Bioloid

I have been searching the best UI (libraries and UI creating tools) multiplatform framework for several years, and QT 5 is the best option I have found. Its libraries are easy to use, specially the slots (UI widgets connection to code) of QT5.  QT Creator is pretty easy to use and the UI designer is the free best tool I have tested. Really I'm learning to use it as creating these examples.

A very simple example:

[caption id="attachment_1508" align="aligncenter" width="287"]QT Bioloid Workshop QT Bioloid Workshop[/caption]

The code uses two classes from the AXControl_v2 library:

- Configuration, it loads the  parameters from the file HexaWheels.conf (currently in spanish):
Tiempo_Espera_ms=36 // wait time
Tiempo_Espera_Sensores_ms=60 // wait time for sensors
Nombre_Puerto_Serie=/dev/ttyUSB0 // serial port name
Baudios_Puerto_Serie=57600 // baud rate

- DynamixelCommunication, it offers the commands to control Dynamixel items

Connecting to the Dynamixel bus:

[sourcecode language="cpp"]
void MainWindow::on_B_Open_clicked()
{
pDynComm->open(); // open the connection using the parameters from the configuration file
setConnectionButtons(true); // enable and disable conveniently the buttons
}
[/sourcecode]

Getting and setting the AX12 Dynamixel position:

[sourcecode language="cpp"]
void MainWindow::on_B_AX12_1_GET_POS_clicked()
{
QString qStr;

int id=ui->SB_AX12_1_ID->text().toInt();
int position = pDynComm->readValue(id, MyCommunications::PresentPosition);
string str=std::to_string(position);

ui->E_AX12_1_POS->setText(qStr.fromStdString(str));
}

void MainWindow::on_B_AX12_1_SET_POS_clicked()
{
QString qStr=ui->SB_AX12_1_ID->text();
int id=Util::convertToInt(qStr.toStdString());

int position= ui->E_AX12_1_POS->text().toInt();
pDynComm->sendOrder(id, MyCommunications::GoalPosition,position);
}

[/sourcecode]

And this is the (unfinished) main window code:

[sourcecode language="cpp"]
#include

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "Configuration.h"
#include "DynamixelCommunication.h"
#include "Util.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
pConf=new Configuration ("/home/jose/proyectos_svn_win/trunk/bioloid/Comun/CPP/AXControl_v2/src/HexaWheels.conf");
pDynComm=new DynamixelCommunication (pConf);
}

MainWindow::~MainWindow()
{
delete ui;

pDynComm->close();
delete pDynComm;
delete pConf;
}

void MainWindow::setConnectionButtons(bool onOff)
{
ui->B_Open->setEnabled(!onOff);
ui->B_Beep->setEnabled(onOff);
ui->B_Close->setEnabled(onOff);
}

void MainWindow::on_B_Open_clicked()
{
//QString output="Open it";
//QMessageBox::information(this, "Output", output, QMessageBox::Ok);

//dynComm.open("/dev/ttyUSB0",57600);
pDynComm->open();

setConnectionButtons(true);
}

void MainWindow::on_B_Beep_clicked()
{
pDynComm->sendOrder(200, MyCommunications::BeepCM510, 5);
}

void MainWindow::on_B_Close_clicked()
{
pDynComm->close();
setConnectionButtons(false);
QString output="Port closed!";
QMessageBox::information(this, "Output", output, QMessageBox::Ok);

}

void MainWindow::on_B_AX12_1_GET_POS_clicked()
{
QString qStr;

int id=ui->SB_AX12_1_ID->text().toInt();
int position = pDynComm->readValue(id, MyCommunications::PresentPosition);
string str=std::to_string(position);

ui->E_AX12_1_POS->setText(qStr.fromStdString(str));
}

void MainWindow::on_B_AX12_1_SET_POS_clicked()
{
QString qStr=ui->SB_AX12_1_ID->text();
int id=Util::convertToInt(qStr.toStdString());

int position= ui->E_AX12_1_POS->text().toInt();
pDynComm->sendOrder(id, MyCommunications::GoalPosition,position);
}

[/sourcecode]

But it's "growing":

[caption id="attachment_1546" align="aligncenter" width="285"]QT_Workbench QT_Workbench[/caption]

I have uploaded the source and binary of this work in progress to
https://www.box.com/s/mdsdeoem0gg4o2rapipj/s/mdsdeoem0gg4o2rapipj

viernes, 1 de marzo de 2013

Workshop: USB, serial and remote communications with C#

[Previous post: Workshop: Dynamixel communications with C#]

[caption id="attachment_1117" align="alignright" width="150"]Bioloid SerialPort2Dynamixel C# Bioloid SerialPort2Dynamixel C#[/caption]

SerialPort2Dynamixel


Encapsulating  the SerialPort .Net class offers an easy way to use the serial port and receive Dynamixel Zig messages with the Dynamixel protocol.

.

.

Collaborator classes:


[caption id="attachment_1134" align="alignright" width="150"]Bioloid SerialPort2Dynamixel C# Collaborators Bioloid SerialPort2Dynamixel C# Collaborators[/caption]

- The SerialPort .Net class.

- RCDataReader class, which unpack the Dynamixel Zigbee sequence offering the clean data received.

Operations:


The public interface that others classes will use offers principally these operations:

public void setRemoteControlMode(bool on), which sets on or off the reception of data

[sourcecode language="csharp"]

public void setRemoteControlMode(bool on)
{
if (on)
setReceiveDataMethod(rdDataReader.rawRemoteDataReceived);
else
setReceiveDataMethod(null);
}

[/sourcecode]

public void setReceiveDataMethod(remoteControlDataReceived rcDataReceived), that sets the method that will be called when serial port data is received.

And some basics serial port data operations:

[caption id="attachment_1112" align="alignright" width="131"]Raspberry Pi - USB2Dynamixel - CM510 Raspberry Pi - USB2Dynamixel - CM510[/caption]

public bool open(String com, int speed), to open the serial port which name is in the com parameter. Wireless communications and USB ports, as used by Zig or USB2Dynaniel, are also serial ports  (COM1, COM2, ... or /ttyUSB0, ttyUSB1).

public void close(), it will do nothing if the port is already closed.

public byte[] query(byte[] buffer, int pos, int wait), send (write) a query and gets (read) the result.

public void rawWrite(byte[] buffer, int pos), well... it will write whatever contains the buffer in the first pos positions

public byte[] rawRead() , read and returns the data received.

Notes:


To avoid concurrency problems all the operations that use the Dynamixel bus are protected with a Mutex object that avoids that two or more concurrent objects use SerialPort2Dynamixel simultaneously entering the same operation or using the same resources, like variables, objects or the Dynamixel bus.

[caption id="attachment_1620" align="aligncenter" width="300"]Xevel USB2AX Xevel USB2AX[/caption]

[caption id="attachment_1622" align="aligncenter" width="300"]USB2AX over USB2DYNAMIXEL USB2AX over USB2DYNAMIXEL[/caption]


RCDataReader


[caption id="attachment_1155" align="alignright" width="150"]Bioloid RCDataReader C# Bioloid RCDataReader C#[/caption]

[caption id="attachment_1128" align="alignleft" width="112"]Remote communications RemoteCommunications[/caption]

Its responsability is to receive the Dynamixel Zig packets and extract the data.

Collaborator class:


- The ZigSequence enum, with the Dynamixels protocols data sections

[caption id="attachment_1171" align="aligncenter" width="300"]RC-100 packet RC-100 packet[/caption]

Operations:


[caption id="attachment_1146" align="alignleft" width="105"]Robotis RC-100 remote controller values Robotis RC-100 remote controller values[/caption]

public void rawRemoteDataReceived(byte[] rcData), receives the Zigbee data.

public int getValue(), returns the last value received