00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ros/ros.h>
00020
00021 #include "naoqi_dcm_driver/dcm.hpp"
00022 #include "naoqi_dcm_driver/tools.hpp"
00023
00024 DCM::DCM(const qi::SessionPtr& session,
00025 const double &controller_freq):
00026 controller_freq_(controller_freq)
00027 {
00028 try
00029 {
00030 dcm_proxy_ = session->service("DCM");
00031 }
00032 catch (const std::exception& e)
00033 {
00034 ROS_ERROR("DCM: Failed to connect to DCM Proxy!\n\tTrace: %s", e.what());
00035 }
00036 }
00037
00038 bool DCM::init(const std::vector <std::string> &joints)
00039 {
00040
00041 createPositionActuatorCommand(joints);
00042
00043
00044 if (!createPositionActuatorAlias(joints))
00045 return false;
00046
00047
00048 if (!createHardnessActuatorAlias(joints))
00049 return false;
00050
00051 return true;
00052 }
00053
00054 void DCM::createPositionActuatorCommand(const std::vector <std::string> &joints)
00055 {
00056
00057 int joints_nbr = joints.size();
00058
00059
00060 commands_.reserve(4);
00061 commands_.resize(4);
00062 commands_[0] = qi::AnyValue(qi::AnyReference::from("jointActuator"), false, false);
00063 commands_[1] = qi::AnyValue(qi::AnyReference::from("ClearAll"), false, false);
00064 commands_[2] = qi::AnyValue(qi::AnyReference::from("time-mixed"), false, false);
00065
00066
00067 commands_values_.reserve(joints_nbr);
00068 commands_values_.resize(joints_nbr);
00069 for(int i=0; i<joints_nbr; ++i)
00070 {
00071 commands_values_[i].resize(1);
00072 commands_values_[i][0].resize(3);
00073 commands_values_[i][0][2] = qi::AnyValue(qi::AnyReference::from(0), false, false);
00074 }
00075
00076 commands_[3] = qi::AnyValue(qi::AnyReference::from(commands_values_), false, false);
00077 }
00078
00079 bool DCM::createPositionActuatorAlias(const std::vector <std::string> &joints)
00080 {
00081
00082 std::vector <qi::AnyValue> commandAlias;
00083 commandAlias.reserve(2);
00084 commandAlias.resize(2);
00085 commandAlias[0] = qi::AnyValue(qi::AnyReference::from("jointActuator"), false, false);
00086
00087
00088 std::vector <qi::AnyValue> commandAlias_keys;
00089 commandAlias_keys.resize(joints.size());
00090 for(int i=0; i<joints.size(); ++i)
00091 {
00092 std::string key = "Device/SubDeviceList/" + joints.at(i) + "/Position/Actuator/Value";
00093 commandAlias_keys[i] = qi::AnyValue(qi::AnyReference::from(key), false, false);
00094 }
00095 commandAlias[1] = qi::AnyValue(qi::AnyReference::from(commandAlias_keys), false, false);
00096
00097 qi::AnyValue commandAlias_qi(qi::AnyReference::from(commandAlias), false, false);
00098
00099
00100 try
00101 {
00102 dcm_proxy_.call<void>("createAlias", commandAlias_qi);
00103 }
00104 catch(const std::exception& e)
00105 {
00106 ROS_ERROR("DCM: Could not create alias for jonts positions!\n\tTrace: %s", e.what());
00107 return false;
00108 }
00109 return true;
00110 }
00111
00112 bool DCM::createHardnessActuatorAlias(const std::vector <std::string> &joints)
00113 {
00114
00115 std::vector <qi::AnyValue> commandAlias;
00116 commandAlias.reserve(2);
00117 commandAlias.resize(2);
00118 commandAlias[0] = qi::AnyValue(qi::AnyReference::from("jointStiffness"), false, false);
00119
00120
00121 std::vector <qi::AnyValue> commandAlias_keys;
00122 for(int i=0; i<joints.size(); ++i)
00123 {
00124 if((joints.at(i) == "RHipYawPitch")
00125 || (joints.at(i).find("Wheel") != std::string::npos))
00126 continue;
00127
00128 std::string key = "Device/SubDeviceList/" + joints.at(i) + "/Hardness/Actuator/Value";
00129 commandAlias_keys.push_back(qi::AnyValue(qi::AnyReference::from(key), false, false));
00130 }
00131 commandAlias[1] = qi::AnyValue(qi::AnyReference::from(commandAlias_keys), false, false);
00132
00133 qi::AnyValue commandAlias_qi(qi::AnyReference::from(commandAlias), false, false);
00134
00135
00136 try
00137 {
00138 dcm_proxy_.call<void>("createAlias", commandAlias_qi);
00139 }
00140 catch(const std::exception& e)
00141 {
00142 ROS_ERROR("DCM: Could not create alias for joints hardness!\n\tTrace: %s", e.what());
00143 return false;
00144 }
00145 return true;
00146 }
00147
00148 bool DCM::DCMAliasTimedCommand(const std::string& alias,
00149 const float& value,
00150 const int& timeOffset,
00151 const std::string& type_update)
00152 {
00153
00154 int time = getTime(timeOffset);
00155
00156
00157 qi::AnyValue command_qi;
00158 try
00159 {
00160 std::vector <qi::AnyValue> command;
00161 command.resize(3);
00162 command[0] = qi::AnyValue(qi::AnyReference::from(alias), false, false);
00163 command[1] = qi::AnyValue(qi::AnyReference::from(type_update), false, false);
00164
00165 std::vector <std::vector <qi::AnyValue> > command_keys;
00166 command_keys.resize(1);
00167 command_keys[0].resize(2);
00168 command_keys[0][0] = qi::AnyValue(qi::AnyReference::from(value), false, false);
00169 command_keys[0][1] = qi::AnyValue(qi::AnyReference::from(time), false, false);
00170
00171 command[2] = qi::AnyValue(qi::AnyReference::from(command_keys), false, false);
00172 command_qi = qi::AnyValue(qi::AnyReference::from(command), false, false);
00173 }
00174 catch(const std::exception& e)
00175 {
00176 ROS_ERROR("DCM: Failed to convert to qi::AnyValue \n\tTrace: %s", e.what());
00177 }
00178
00179
00180 try
00181 {
00182 dcm_proxy_.call<void>("set", command_qi);
00183 return false;
00184 }
00185 catch(const std::exception& e)
00186 {
00187 ROS_ERROR("DCM: Failed to execute DCM timed-command! \n\tTrace: %s", e.what());
00188 }
00189 return true;
00190 }
00191
00192 int DCM::getTime(const int &offset)
00193 {
00194 int res;
00195 try
00196 {
00197 res = dcm_proxy_.call<int>("getTime", 0) + offset;
00198 }
00199 catch(const std::exception& e)
00200 {
00201 ROS_ERROR("DCM: Failed to get time! \n\tTrace: %s", e.what());
00202 }
00203 return res;
00204 }
00205
00206 void DCM::writeJoints(const std::vector <double> &joint_commands)
00207 {
00208 int time = getTime(static_cast<int>(5000.0/controller_freq_));
00209
00210
00211 qi::AnyValue commands_qi;
00212 try
00213 {
00214 std::vector<double>::const_iterator it_comm = joint_commands.begin();
00215 for(int i=0; i<joint_commands.size(); ++i, ++it_comm)
00216 {
00217 commands_values_[i][0][0] = qi::AnyValue(qi::AnyReference::from(static_cast<float>(*it_comm)), false, false);
00218 commands_values_[i][0][1] = qi::AnyValue(qi::AnyReference::from(time), false, false);
00219 }
00220
00221 commands_[3] = qi::AnyValue(qi::AnyReference::from(commands_values_), false, false);
00222 commands_qi = qi::AnyValue(qi::AnyReference::from(commands_), false, false);
00223 }
00224 catch(const std::exception& e)
00225 {
00226 ROS_ERROR("DCM: Failed to convert to qi::AnyValue \n\tTrace: %s", e.what());
00227 }
00228
00229
00230 try
00231 {
00232 dcm_proxy_.call<void>("setAlias", commands_qi);
00233 }
00234 catch(const std::exception& e)
00235 {
00236 ROS_ERROR("DCM: Failed to execute DCM timed-command! \n\tTrace: %s", e.what());
00237 }
00238 }
00239
00240 bool DCM::setStiffness(const float &stiffness)
00241 {
00242
00243 return DCMAliasTimedCommand("jointStiffness", stiffness, 1000);
00244 }