SoftBank Robotics documentation What's new in NAOqi 2.8?

Creating a custom main

Sometimes you may want to change the main.cpp of your module.

A typicall case may be to change the option parsing, or not use the big black box which is ALTools::mainFunction

main.cpp

#include <iostream>


#include <boost/shared_ptr.hpp>
#include <alerror/alerror.h>
#include <alcommon/albroker.h>
#include <alcommon/albrokermanager.h>

int main(int argc, char* argv[])
{

  if(argc < 2)
  {
    std::cerr << "Usage: custommain NAO_IP" << std::endl;
    return 2;
  }

  // We will try to connect our broker to an running NAOqi:
  const std::string parentBrokerIP = std::string(argv[1]);
  int parentBrokerPort = 9559;

  // Need this to for SOAP serialization of floats to work
  setlocale(LC_NUMERIC, "C");

  // A broker needs a name, an IP and a port:
  const std::string brokerName = "mybroker";
  // FIXME: would be a good idea to look for a free port first
  int brokerPort = 54000;
  const std::string brokerIp   = "0.0.0.0";  // listen to anything

  boost::shared_ptr<AL::ALBroker> broker;
  try
  {
    broker = AL::ALBroker::createBroker(
        brokerName,
        brokerIp,
        brokerPort,
        parentBrokerIP,
        parentBrokerPort,
        0    // you can pass various options for the broker creation,
             // but default is fine
      );
  }
  catch(const AL::ALError& /* e */)
  {
    std::cerr << "Faild to connect broker to: "
              << parentBrokerIP
              << ":"
              << parentBrokerPort
              << std::endl;
    AL::ALBrokerManager::getInstance()->killAllBroker();
    AL::ALBrokerManager::kill();
    return 1;
  }

  // Deal with ALBrokerManager singleton:
  AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
  AL::ALBrokerManager::getInstance()->addBroker(broker);

  // Now it's time to load your module with
  // AL::ALModule::createModule<YourModule>(broker, "YourModule");

  return 0;
}

Some few remarks:

  • The call to setlocale is very important. Due to SOAP issues, you must make sure your client and your server are using the same LC_NUMERIC settings.
  • In the example there is no parsing of options, so you must add the code to handle --pip and --pport yourself. Using boost::program_options, this looks like:
#include <boost/program_options.hpp>
#include <qi/application.hpp>
namespace po = boost::program_options;
po::options_description desc("Allowed options");

int main(int argc, char* argv[])
{

  std::string parentBrokerIP;
  int parentBrokerPort;


  qi::Application app(argc, argv);
  po::options_description desc("Allowed options");


  desc.add_options()
    ("pip", po::value<std::string>(&parentBrokerIP)->default_value("127.0.0.1"), "IP of the parent broker. Default: 127.0.0.1")
    ("pport", po::value<int>(&parentBrokerPort)->default_value(9559), "Port of the parent broker. Default: 9559")
    ;


  // Map containing all the options with their values
  po::variables_map vm;

  // program option library throws all kind of errors, we just catch them
  // all, print usage and exit
  try
  {
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);
  }
  catch(po::error &e)
  {
    std::cerr << e.what() << std::endl;
    std::cout << desc << std::endl;
    exit(1);
  }


  // Now use parentBrokerIP, parentBrokerPort when creating ALBroker