Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to match NAOqi 2.9 fixes in driver_helper and add warning for port to README #6

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ for robots running NAOqi 2.9 or greater:
ros2 launch naoqi_driver naoqi_driver.launch.py nao_ip:=<robot_host> nao_username:=nao nao_password:=<robot_password> qi_listen_url:=tcp://0.0.0.0:0
```

Warning: If you have a `connection refused error` such as [this issue](https://github.com/ros-naoqi/naoqi_driver/issues/162)
(from ROS1 driver version) when using robots running NAOqi 2.8 and greater, please try to give `nao_port:=9503` explicitly.

### From a Docker container

Expand Down
278 changes: 176 additions & 102 deletions src/helpers/driver_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/

#include "driver_helpers.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

namespace naoqi
{
Expand All @@ -24,6 +26,10 @@ namespace helpers
namespace driver
{

namespace pt = boost::property_tree;

static pt::ptree empty_ptree;

/** Function that returns the type of a robot
*/
static naoqi_bridge_msgs::msg::RobotInfo& getRobotInfoLocal( const qi::SessionPtr& session)
Expand Down Expand Up @@ -68,112 +74,180 @@ static naoqi_bridge_msgs::msg::RobotInfo& getRobotInfoLocal( const qi::SessionPt

// Get the data from RobotConfig
qi::AnyObject p_motion = session->service("ALMotion").value();
std::vector<std::vector<qi::AnyValue> > config = p_motion.call<std::vector<std::vector<qi::AnyValue> > >("getRobotConfig");

// TODO, fill with the proper string matches from http://doc.aldebaran.com/2-1/naoqi/motion/tools-general-api.html#ALMotionProxy::getRobotConfig

for (size_t i=0; i<config[0].size();++i)
{
if (config[0][i].as<std::string>() == "Model Type")
{
try{
info.model = config[1][i].as<std::string>();
}
catch(const std::exception& e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Head Version")
try
{
try{
info.head_version = config[1][i].as<std::string>();
}
catch(const std::exception& e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
std::vector<std::vector<qi::AnyValue>> config = p_motion.call<std::vector<std::vector<qi::AnyValue>>>("getRobotConfig");

// TODO, fill with the proper string matches from http://doc.aldebaran.com/2-1/naoqi/motion/tools-general-api.html#ALMotionProxy::getRobotConfig

for (size_t i = 0; i < config[0].size(); ++i)
{
if (config[0][i].as<std::string>() == "Model Type")
{
try
{
info.model = config[1][i].as<std::string>();
}
catch (const std::exception &e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Head Version")
{
try
{
info.head_version = config[1][i].as<std::string>();
}
catch (const std::exception &e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Body Version")
{
try
{
info.body_version = config[1][i].as<std::string>();
}
catch (const std::exception &e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Arm Version")
{
try
{
info.arm_version = config[1][i].as<std::string>();
}
catch (const std::exception &e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Laser")
{
try
{
info.has_laser = config[1][i].as<bool>();
}
catch (const std::exception &e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Extended Arms")
{
try
{
info.has_extended_arms = config[1][i].as<bool>();
}
catch (const std::exception &e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Number of Legs")
{
try
{
info.number_of_legs = config[1][i].as<int>();
}
catch (const std::exception &e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Number of Arms")
{
try
{
info.number_of_arms = config[1][i].as<int>();
}
catch (const std::exception &e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Number of Hands")
{
try
{
info.number_of_hands = config[1][i].as<int>();
}
catch (const std::exception &e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}
}
}

if (config[0][i].as<std::string>() == "Body Version")
{
try{
info.body_version = config[1][i].as<std::string>();
}
catch(const std::exception& e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Arm Version")
{
try{
info.arm_version = config[1][i].as<std::string>();
}
catch(const std::exception& e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Laser")
catch (...)
{
try{
info.has_laser = config[1][i].as<bool>();
}
catch(const std::exception& e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
// NAOqi 2.9
std::cout << "ALMotion.getRobotConfig failed (" /*<< e.what()*/ << "), trying with newer service ALRobotModel" << std::endl;
auto p_robot_model = session->service("ALRobotModel").value();

try
{
info.model = p_robot_model.call<std::string>("getRobotType");
}
catch (const std::exception &e)
{
std::cout << "Error getting robot type (with ALRobotModel.getRobotType): " << e.what() << std::endl;
}

try
{
info.number_of_legs = p_robot_model.call<bool>("hasLegs") ? 1 : 0;
}
catch (const std::exception &e)
{
std::cout << "Error getting robot type (with ALRobotModel.getRobotType): " << e.what() << std::endl;
}

try
{
std::istringstream config_data(p_robot_model.call<std::string>("getConfig"));
pt::ptree tree;
pt::read_xml(config_data, tree);

auto preferences = tree.get_child("ModulePreference");
for (const auto& pref: preferences) {
if (pref.first != "Preference")
continue;
const pt::ptree& attributes = pref.second.get_child("<xmlattr>", empty_ptree);

const auto& memory_key = attributes.get<std::string>("memoryName");
if (memory_key == "RobotConfig/Head/Version") {
info.head_version = attributes.get<std::string>("value");
} else if (memory_key == "RobotConfig/Body/Version") {
info.body_version = attributes.get<std::string>("value");
} else if (memory_key == "RobotConfig/Body/Device/LeftArm/Version") {
info.arm_version = attributes.get<std::string>("value");
}
}
}
catch (const std::exception &e)
{
std::cout << "Error getting head version (with ALRobotModel.getConfig): " << e.what() << std::endl;
}

// Some data is missing, but anyways only Pepper 1.8 is supported by NAOqi 2.9.
info.has_laser = false;
info.has_extended_arms = false;
info.number_of_arms = 2;
info.number_of_hands = 2;
}

if (config[0][i].as<std::string>() == "Extended Arms")
{
try{
info.has_extended_arms = config[1][i].as<bool>();
}
catch(const std::exception& e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Number of Legs")
{
try{
info.number_of_legs = config[1][i].as<int>();
}
catch(const std::exception& e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Number of Arms")
{
try{
info.number_of_arms = config[1][i].as<int>();
}
catch(const std::exception& e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

if (config[0][i].as<std::string>() == "Number of Hands")
{
try{
info.number_of_hands = config[1][i].as<int>();
}
catch(const std::exception& e)
{
std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
}
}

}
return info;
}

Expand Down