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

Setup assistant automating generation of controllers configs #908

Closed
Closed
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fa6a3d5
add new function for generating controllers
mayman99 May 19, 2018
3fc2678
output controllers file
mayman99 May 21, 2018
644884e
Merge branch 'kinetic-devel' of https://github.com/ros-planning/movei…
mayman99 May 21, 2018
bf5d682
cleaning a comment
mayman99 May 21, 2018
8d765c6
removed fake controllers
mayman99 May 21, 2018
63cfe2a
added controllers launch file
mayman99 May 21, 2018
b06bc6f
re-added fake controllers for backward compatibility
mayman99 May 22, 2018
6c5380d
fixed clang format error
mayman99 May 22, 2018
e9e9d31
renamed controllers launch to ros_controllers_launch
mayman99 May 23, 2018
7a6c6e8
output the joints in each group
mayman99 May 23, 2018
faaa778
replaced controllers.launch by ros_controllers.launch
mayman99 May 23, 2018
ce69772
fixed clang formating errors
mayman99 May 23, 2018
e48a590
added MoveIt-specific simulation settings
mayman99 May 25, 2018
b75e461
Merge branch 'kinetic-devel' of https://github.com/ros-planning/movei…
mayman99 May 25, 2018
c2cc610
improved documentaion and style
mayman99 May 25, 2018
7ed61e0
replace int by std::size_t
mayman99 May 25, 2018
b72b3e8
renamed controllers.yaml to ros_controllers.yaml
mayman99 May 26, 2018
07e3ac8
Merge branch 'kinetic-devel' of https://github.com/ros-planning/movei…
mayman99 May 26, 2018
6dcadd2
Merge branch 'kinetic-devel' of https://github.com/ros-planning/movei…
mayman99 May 29, 2018
322c6d5
renamed outputControllersYAML to outputROSControllersYAML and replace…
mayman99 May 29, 2018
2364497
removed absolute namespacing
mayman99 May 29, 2018
b44c197
use relative namespacing
mayman99 May 29, 2018
92544a1
fix function name in config files widget
mayman99 May 29, 2018
0c1b91e
use robot name for namespacing
mayman99 May 29, 2018
64a266c
Merge branch 'kinetic-devel' of https://github.com/ros-planning/movei…
mayman99 May 29, 2018
3f9ee4c
Merge branch 'kinetic-devel' of https://github.com/ros-planning/movei…
mayman99 May 30, 2018
c929678
rename namespace to setup_assistant
mayman99 May 30, 2018
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
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class MoveItConfigData
bool outputKinematicsYAML(const std::string& file_path);
bool outputJointLimitsYAML(const std::string& file_path);
bool outputFakeControllersYAML(const std::string& file_path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets keep the fake controllers also

bool outputControllersYAML(const std::string& file_path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outputROSControllersYAML?


/**
* \brief Set list of collision link pairs in SRDF; sorted; with optional filter
Expand Down
178 changes: 178 additions & 0 deletions moveit_setup_assistant/src/tools/moveit_config_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,184 @@ bool MoveItConfigData::outputFakeControllersYAML(const std::string& file_path)
return true; // file created successfully
}

// ******************************************************************************************
// Output controllers config files
// ******************************************************************************************
bool MoveItConfigData::outputControllersYAML(const std::string& file_path)
{
// Cache the joints' names.
std::vector<std::vector<std::string>> planning_groups;
std::vector<std::string> group_joints;

// We are going to write the joints names many times.
// Loop through groups to store the joints names in group_joints vector and reuse is.
for (std::vector<srdf::Model::Group>::iterator group_it = srdf_->groups_.begin(); group_it != srdf_->groups_.end();
++group_it)
{
// Get list of associated joints
const robot_model::JointModelGroup* joint_model_group = getRobotModel()->getJointModelGroup(group_it->name_);
const std::vector<const robot_model::JointModel*>& joint_models = joint_model_group->getActiveJointModels();
// Iterate through the joints and push into group_joints vector.
for (const robot_model::JointModel* joint : joint_models)
{
if (joint->isPassive() || joint->getMimic() != NULL || joint->getType() == robot_model::JointModel::FIXED)
continue;
else
group_joints.push_back(joint->getName());
}
// Push all the group joints into planning_groups vector.
planning_groups.push_back(group_joints);
group_joints.clear();
}

YAML::Emitter emitter;
emitter << YAML::BeginMap;

emitter << YAML::Comment("MoveIt-specific simulation settings");
emitter << YAML::Key << "moveit_sim_hw_interface" << YAML::Value << YAML::BeginMap;
emitter << YAML::Key << "joint_model_group";
emitter << YAML::Value << "manipulator";
emitter << YAML::Key << "joint_model_group_pose";
emitter << YAML::Value << "up";
emitter << YAML::Key << "cycle_time_error_threshold";
emitter << YAML::Value << "0.01";
emitter << YAML::EndMap;

emitter << YAML::Newline;
emitter << YAML::Comment("Settings for ros_control control loop");
emitter << YAML::Key << "generic_hw_control_loop" << YAML::Value << YAML::BeginMap;
emitter << YAML::Key << "loop_hz";
emitter << YAML::Value << "300";
emitter << YAML::Key << "cycle_time_error_threshold";
emitter << YAML::Value << "0.01";
emitter << YAML::EndMap;

emitter << YAML::Newline;
emitter << YAML::Comment("Settings for ros_control hardware interface");
emitter << YAML::Key << "hardware_interface";
emitter << YAML::Value << YAML::BeginMap;
// Loop through groups
for (std::size_t i = 0; i < srdf_->groups_.size(); ++i)
{
emitter << YAML::Key << "name";
emitter << YAML::Value << srdf_->groups_[i].name_ + "_controller";
emitter << YAML::Key << "joints";
emitter << YAML::Value << YAML::BeginSeq;

// Iterate through the joints
for (std::size_t j = 0; j < planning_groups[i].size(); j++)
{
emitter << planning_groups[i][j];
}
emitter << YAML::EndSeq;
}
emitter << YAML::Key << "sim_control_mode";
emitter << YAML::Value << "1";
emitter << YAML::Comment("0: position, 1: velocity");
emitter << YAML::Newline;
emitter << YAML::Comment("Publish all joint states");
emitter << YAML::Newline << YAML::Comment("Creates the /joint_states topic necessary in ROS");
emitter << YAML::EndMap;

emitter << YAML::Key << "joint_state_controller";
emitter << YAML::Value << YAML::BeginMap;
emitter << YAML::Key << "type";
emitter << YAML::Value << "joint_state_controller/JointStateController";
emitter << YAML::Key << "publish_rate";
emitter << YAML::Value << "50";
emitter << YAML::Newline;
emitter << YAML::Comment("Joint Trajectory Controller");
emitter << YAML::Newline << YAML::Comment("For detailed explanations of parameter see "
"http://wiki.ros.org/joint_trajectory_controller");

emitter << YAML::EndMap;

emitter << YAML::Key << "position_trajectory_controller";
emitter << YAML::Value << YAML::BeginMap;
emitter << YAML::Key << "type";
emitter << YAML::Value << "position_controllers/JointTrajectoryController";
// Loop through groups
for (std::size_t i = 0; i < srdf_->groups_.size(); ++i)
{
// emitter << YAML::BeginMap;
emitter << YAML::Key << "name";
emitter << YAML::Value << srdf_->groups_[i].name_ + "_controller";
emitter << YAML::Key << "joints";
emitter << YAML::Value << YAML::BeginSeq;

// Iterate through the joints
for (std::size_t j = 0; j < planning_groups[i].size(); j++)
{
emitter << planning_groups[i][j];
}
emitter << YAML::EndSeq;
}
emitter << YAML::Key << "constraints";
emitter << YAML::Value << YAML::BeginMap;
emitter << YAML::Key << "goal_time";
emitter << YAML::Value << "5.0";
// Loop through groups
for (std::size_t i = 0; i < srdf_->groups_.size(); ++i)
{
emitter << YAML::Key << "name";
emitter << YAML::Value << srdf_->groups_[i].name_ + "_controller";
emitter << YAML::Key << "joints";
emitter << YAML::Value << YAML::BeginSeq;

// Iterate through the joints
for (std::size_t j = 0; j < planning_groups[i].size(); j++)
{
emitter << YAML::BeginMap;
emitter << YAML::Key << planning_groups[i][j] << YAML::Value << YAML::BeginMap;
emitter << YAML::Key << "trajectory";
emitter << YAML::Value << "0.60";
emitter << YAML::Key << "goal";
emitter << YAML::Value << "0.15";
emitter << YAML::EndMap;
emitter << YAML::EndMap;
}
emitter << YAML::EndSeq;
}
emitter << YAML::EndMap;
emitter << YAML::EndMap;
emitter << YAML::Newline;

emitter << YAML::Comment("Group Position Controllers");
emitter << YAML::Comment("Allows to send single ROS msg of Float64MultiArray to all joints");
emitter << YAML::Key << "joint_position_controller";
emitter << YAML::Value << YAML::BeginMap;
emitter << YAML::Key << "type";
emitter << YAML::Value << "position_controllers/JointGroupPositionController";
// Loop through groups
for (std::size_t i = 0; i < srdf_->groups_.size(); ++i)
{
emitter << YAML::Key << "name";
emitter << YAML::Value << srdf_->groups_[i].name_ + "_controller";
emitter << YAML::Key << "joints";
emitter << YAML::Value << YAML::BeginSeq;

// Iterate through the joints
for (std::size_t j = 0; j < planning_groups[i].size(); j++)
{
emitter << planning_groups[i][j];
}
emitter << YAML::EndSeq;
}
emitter << YAML::EndMap;
emitter << YAML::EndMap;

std::ofstream output_stream(file_path.c_str(), std::ios_base::trunc);
if (!output_stream.good())
{
ROS_ERROR_STREAM("Unable to open file for writing " << file_path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ROS_ERROR_STREAM_NAMED

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you recommend using the Named version here?
All the functions here that cant output a file uses this
ROS_ERROR_STREAM("Unable to open file for writing " << file_path);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the style guidelines under "ROS":
http://moveit.ros.org/documentation/contributing/code/

It makes filtering all the command line output much easier and cleaner. All of the MSA should be updated to use NAMED, but that belongs in a separate simple PR that doesn't clutter this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I understand, Thanks.

return false;
}
output_stream << emitter.c_str();
output_stream.close();

return true; // file created successfully
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function is very long and readability is low. can it be separated out into a few smaller functions for each section of the yaml?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can split it, but I think later we will have to change this function when we expose some of the options to be configured by the GUI, would it be okay to leave it as a one piece until then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, no problem.

}

// ******************************************************************************************
// Output joint limits config files
// ******************************************************************************************
Expand Down
17 changes: 17 additions & 0 deletions moveit_setup_assistant/src/widgets/configuration_files_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,14 @@ bool ConfigurationFilesWidget::loadGenFiles()
file.write_on_changes = MoveItConfigData::GROUPS;
gen_files_.push_back(file);

// ros_controllers.yaml --------------------------------------------------------------------------------------
file.file_name_ = "ros_controllers.yaml";
file.rel_path_ = config_data_->appendPaths(config_path, file.file_name_);
file.description_ = "Creates configurations for ros_controllers.";
file.gen_func_ = boost::bind(&MoveItConfigData::outputControllersYAML, config_data_, _1);
file.write_on_changes = MoveItConfigData::GROUPS;
gen_files_.push_back(file);

// -------------------------------------------------------------------------------------------------------------------
// LAUNCH FILES ------------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -472,6 +480,15 @@ bool ConfigurationFilesWidget::loadGenFiles()
file.write_on_changes = 0;
gen_files_.push_back(file);

// ros_controllers.launch ------------------------------------------------------------------
file.file_name_ = "ros_controllers.launch";
file.rel_path_ = config_data_->appendPaths(launch_path, file.file_name_);
template_path = config_data_->appendPaths(template_launch_path, "ros_controllers.launch");
file.description_ = "ros_controllers launch file";
file.gen_func_ = boost::bind(&ConfigurationFilesWidget::copyTemplate, this, template_path, _1);
file.write_on_changes = MoveItConfigData::GROUPS;
gen_files_.push_back(file);

// moveit.rviz ------------------------------------------------------------------
file.file_name_ = "moveit.rviz";
file.rel_path_ = config_data_->appendPaths(launch_path, file.file_name_);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<launch>

<!-- Load joint controller configurations from YAML file to parameter server -->
<rosparam file="$(find [GENERATED_PACKAGE_NAME])/config/ros_controllers.yaml" command="load"/>

<!-- Load the controllers -->
<node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
output="screen" ns="/[GENERATED_PACKAGE_NAME]" args="spawn joint_state_controller position_trajectory_controller"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@willcbaker Is using absolute namespaces compatible to 4598f66?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe so, I would advise against absolute namespacing.
Unable to test or review until next week, seems changing this way with generated package name will require pushing down into package name namespace?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you recommend to remove the ns argument from here and from the robot_state_publisher node? right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ros_controllers.launch is intended to be used with gazebo, and according to ros_control tutorials, this is how gazebo_ros_control plugin is defined in the urdf

<gazebo>
  <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
    <robotNamespace>/MYROBOT</robotNamespace>
  </plugin>
</gazebo>

So if we were to launch the controllers with not the robot_name as a namespace , and leave the plugin element <robotNamespace> blank, how would we be able to use simulate multiple robot for example?
Is there a solution for a situation like that?


<!-- Convert joint states to TF transforms for rviz, etc -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"
respawn="false" output="screen">
<remap from="/joint_states" to="/[GENERATED_PACKAGE_NAME]/joint_states" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

</node>

</launch>