Bioloid Workbench Windows C++ examples

This entry is part 6 of 6 in the series Bioloid Workshop

This post presents the Windows version of two examples/utilities built, this time, with MS Visual C++ and QT Creator, a great open source IDE and framework.

The first utility has a comand line user interface, being an easy example with only two DLL dependencies to the Visual C++ runtimes.

Screenshot-Terminal

The second example utility has a graphic user interface created with QT Creator.

QTWorkbench

Here you can find the bin executables and the projects with the source code.

This is the main function of the first example, the command line:

int _tmain(int argc, _TCHAR* argv[])
{
  cout << "AXControl_v2_VS_CPP test v0" << endl;

  bool quit=false;
  MyBasicSystem::BasicSystem mySystem;
  UI ui(mySystem);
  do
  {
    ui.showMenu();
    int selected=ui.selectOption();
    if (selected==ui.OptionQuit)
	quit=true;
    ui.executeSelectedOption(selected);
  }while (!quit);

  mySystem.dynamixelCommunication.close();

	return 0;
}

[Update] Yesterday I discovered a subtle but ugly bug. Can you spot it? Send an email to if you can’t find it but you want to know the danger bug.

It use two classes, the “BasicSystem” (in the library “VS_CPP_AXControl_lib.lib”) and a simple “UI” class that receives the input from the user and use the operations offered by the “BasicSystem” class.

For example:

int UI::getPosition()
{
  int position=0;

  do
  {
    cout << "Type a value between 0 and 1023 to set the AX-12 in that position" << endl;     cin>>position;

  }while(!validRange(position, 0, 1023));

  cout << "Position:" <<  position << endl;

  return position;
}
...
void UI::doSetPosition()
{
  int ax12Id=getId();
  int position=getPosition();

  mySystem.dynamixelCommunication.sendOrder(ax12Id, MyCommunications::GoalPosition,(short) position);
}

And all the cource code:

/*------------------------------------------------------------------------------*\
 * This source file is subject to the GPLv3 license that is bundled with this   *
 * package in the file COPYING.                                                 *
 * It is also available through the world-wide-web at this URL:                 *
 * http://www.gnu.org/licenses/gpl-3.0.txt                                      *
 * If you did not receive a copy of the license and are unable to obtain it     *
 * through the world-wide-web, please send an email to                          *
 * siempre.aprendiendo@gmail.com so we can send you a copy immediately.         *
 *                                                                              *
 * @category  Robotics                                                          *
 * @copyright Copyright (c) 2011 Jose Cortes (http://www.siempreaprendiendo.es) *
 * @license   http://www.gnu.org/licenses/gpl-3.0.txt GNU v3 Licence            *
 *                                                                              *
\*------------------------------------------------------------------------------*/

#include "stdafx.h"
#include
#include "BasicSystem.h"
#include "Util.h"

using namespace std;

class UI
{
public:
  static const int OptionQuit=8;

  UI(MyBasicSystem::BasicSystem& aMySystem) : mySystem(aMySystem) {}

  void showMenu();
  int selectOption();
  bool executeSelectedOption(int selected);
  void doBeep();

private:
  MyBasicSystem::BasicSystem mySystem;

  static const int OptionSetLEDOnOff=1;
  static const int OptionQueryAX12=2;
  static const int OptionMoveAX12=3;
  static const int OptionTorqueAX12=4;
  static const int OptionQuerySensor=5;
  static const int OptionShowMenu=6;
  static const int OptionBeep=7;

  static const int MinOption=OptionSetLEDOnOff;
  static const int MaxOption=OptionQuit;

  bool validRange(int value, int MinValue, int MaxValue);
  bool nonValidOption(int option);
  int getPosition();
  int getId();
  int getSensorPort();
  void doGetPosition();
  void doSetPosition();
  void doQuerySensor();
  void doSetLEDOnOff();
  void doSetTorqueOnOff();

};

void UI::showMenu()
{
  cout << "V02" << endl;

  cout << OptionSetLEDOnOff << ".- Toggle AX-12 LED" << endl;
  cout << OptionQueryAX12 << ".- Query AX-12" << endl;
  cout << OptionMoveAX12 << ".- Move AX-12" << endl;
  cout << OptionTorqueAX12 << ".- Torque AX-12" << endl;
  cout << OptionQuerySensor << ".- Query CM-510 sensor" << endl;
  cout << OptionShowMenu << ".- Show menu" << endl;
  cout << OptionBeep << ".- Beep" << endl;
  cout << OptionQuit << ".- Quit" << endl;
}

bool UI::nonValidOption(int option)
{
  return (optionMaxOption);
}

int UI::selectOption()
{
  int option=-1;

  while (nonValidOption(option))
  {
    cout << "Select option (" << MinOption << "-" << MaxOption << ")" << endl;     cin >> option;
    if (nonValidOption(option))
    {
      cout << endl;
      cout << endl;
      cout << "(" << option << ") is NOT a valid option" << endl;     }     }   return option; } bool UI::validRange(int value, int MinValue, int MaxValue) {		   return (value>=MinValue && value<=MaxValue);
}

int UI::getPosition()
{
  int position=0;

  do
  {
    cout << "Type a value between 0 and 1023 to set the AX-12 in that position" << endl;     cin>>position;

  }while(!validRange(position, 0, 1023));

  cout << "Position:" <<  position << endl;   return position; } int UI::getId() {   int ax12Id=1;        do    {	     puts ("Type the ID of the AX-12 to use, a value between 1 and 18, ");     cin >> ax12Id;

  }while(!validRange(ax12Id, 1, 18));

  cout << "AX12 Id:" << ax12Id << endl;   return ax12Id; } int UI::getSensorPort() {   int sensorPort=1;        do    {	     puts ("Type the sensor Port to read, a value between 1 and 6, ");     cin >> sensorPort;

  }while(!validRange(sensorPort, 1, 6));

  cout << "Sensor Port number:" << sensorPort << endl;

  return sensorPort;
}

void UI::doBeep()
{
  cout << "Beep" << endl;
  mySystem.dynamixelCommunication.sendOrder(100, AXS1_Buzzer, (byte) DO, (short) 500);
  Sleep (2);
  mySystem.dynamixelCommunication.sendOrder(200, MyCommunications::Beep, (byte) 5);
}

void UI::doGetPosition()
{
  int ax12Id=getId();

  int position = mySystem.dynamixelCommunication.readValue(ax12Id, MyCommunications::PresentPosition);
  cout << "the position is: [" << position << "] " << endl << endl << endl;
}

void UI::doSetPosition()
{
  int ax12Id=getId();
  int position=getPosition();

  mySystem.dynamixelCommunication.sendOrder(ax12Id, MyCommunications::GoalPosition,(short) position);
}

void UI::doQuerySensor()
{
  int sensorPort=getSensorPort();

  int value=mySystem.dynamixelCommunication.readSensorValue (200, ReadCM510SensorRaw, sensorPort);
  cout << "the sensor reads: [" << value << "] " << endl << endl << endl;
}

void UI::doSetLEDOnOff()
{
  byte lByte=0, hByte=0;
  int ledValue;

  int ax12Id=getId();

  ledValue=mySystem.dynamixelCommunication.readValue(ax12Id, MyCommunications::LED);
  Hex::toHexHLConversion(ledValue, hByte, lByte);

  bool onOff=false;
  if (lByte!=0)
    onOff=true;

  cout << "The LED is: [" << (onOff?"on":"off") << "], putting it: [" << (onOff?"Off":"on") << "] " << endl << endl << endl;
  mySystem.dynamixelCommunication.sendOrder(ax12Id, MyCommunications::LED, byte(onOff?0:1));
}

void UI::doSetTorqueOnOff()
{
  byte lByte=0, hByte=0;
  int ax12Id=getId();

  int torque=mySystem.dynamixelCommunication.readValue(ax12Id, MyCommunications::Torque);
  Hex::toHexHLConversion(torque, hByte, lByte);
  bool onOff=(lByte!=0?true:false);

  cout << "The Torque is: [" << (onOff?"on":"off") << "], putting it: [" << (onOff?"Off":"on") << "] " << endl << endl << endl;

  mySystem.dynamixelCommunication.sendOrder(ax12Id, MyCommunications::Torque,(byte) (onOff?0:1));
}

bool UI::executeSelectedOption(int option)
{
  bool isOk=true;
  cout << endl;
  cout << endl;

  cout << "Selected option: [" << option << "] " << endl;   switch(option)   {     case OptionSetLEDOnOff:          doSetLEDOnOff();           break;     case OptionQueryAX12:          doGetPosition();          break;     case OptionMoveAX12:          doSetPosition();           break;     case OptionTorqueAX12:          doSetTorqueOnOff();          break;     case OptionQuerySensor:          doQuerySensor();          break;     case OptionShowMenu: 	 showMenu(); 	 break;     case OptionBeep:          doBeep();          break;   }   return isOk; } 

The code for the Qt version is more complex, but as an example, the same operation that the example for the command line:

 int MainWindow::getAX12_1_Id() {     // Get the value from the edit control for the first AX-12     QString qStr=ui->SB_AX12_1_ID->text();
    int id=Util::convertToInt(qStr.toStdString());

    return id;
}
...
void MainWindow::on_B_AX12_1_SET_POS_clicked()
{
    int id = getAX12_1_Id();

    // Get the target position from the UI edit control as string and a convert it to int
    short position= ui->SB_AX12_1_POS->text().toInt();

    // Send the order to the AX-12 with the "id" to go to "position"
    pDynComm->sendOrder(id, MyCommunications::GoalPosition,position);
}
Series Navigation<< [UPDATED] A simple but pretty complete Linux C++ example for Bioloid

Comments are closed.

%d bloggers like this: