-
Notifications
You must be signed in to change notification settings - Fork 947
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
Changes from 18 commits
fa6a3d5
3fc2678
644884e
bf5d682
8d765c6
63cfe2a
b06bc6f
6c5380d
e9e9d31
7a6c6e8
faaa778
ce69772
e48a590
b75e461
c2cc610
7ed61e0
b72b3e8
07e3ac8
6dcadd2
322c6d5
2364497
b44c197
92544a1
0c1b91e
64a266c
3f9ee4c
c929678
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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); | ||
bool outputControllersYAML(const std::string& file_path); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use ROS_ERROR_STREAM_NAMED There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you recommend using the Named version here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See the style guidelines under "ROS": 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, no problem. |
||
} | ||
|
||
// ****************************************************************************************** | ||
// Output joint limits config files | ||
// ****************************************************************************************** | ||
|
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"/> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @willcbaker Is using absolute namespaces compatible to 4598f66? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't believe so, I would advise against absolute namespacing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you recommend to remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I think so. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This
So if we were to launch the controllers with not the |
||
|
||
<!-- 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" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
</node> | ||
|
||
</launch> |
There was a problem hiding this comment.
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