-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from marip8/update/python-interface
Python interface updates
- Loading branch information
Showing
13 changed files
with
213 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*.pyc | ||
*.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,4 +9,4 @@ | |
- git: | ||
local-name: reach | ||
uri: https://github.com/ros-industrial/reach.git | ||
version: 1.3.0 | ||
version: 1.4.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from reach_ros.utils import * | ||
from _reach_ros import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from reach import SEARCH_LIBRARIES_ENV | ||
|
||
from rclpy.parameter import Parameter, PARAMETER_SEPARATOR_STRING | ||
import yaml | ||
import os | ||
|
||
|
||
def parse_parameter_dict(*, namespace, parameter_dict): | ||
parameters = [] | ||
for param_name, param_value in parameter_dict.items(): | ||
full_param_name = namespace + param_name | ||
# Unroll nested parameters | ||
if type(param_value) == dict: | ||
parameters += parse_parameter_dict( | ||
namespace=full_param_name + PARAMETER_SEPARATOR_STRING, | ||
parameter_dict=param_value) | ||
else: | ||
parameter = Parameter(name=full_param_name, value=param_value) | ||
parameters.append(parameter) | ||
return parameters | ||
|
||
|
||
def parse_yaml(parameter_file, namespace=''): | ||
with open(parameter_file, 'r') as f: | ||
param_dict = yaml.safe_load(f) | ||
return parse_parameter_dict(namespace=namespace, parameter_dict=param_dict) | ||
|
||
|
||
def update_search_libraries_env(): | ||
""" Updates the search libraries environment variable to include the plugin library provided by this package | ||
:return: | ||
""" | ||
if os.environ.get(SEARCH_LIBRARIES_ENV) is None: | ||
os.environ[SEARCH_LIBRARIES_ENV] = 'reach_ros_plugins' | ||
else: | ||
os.environ[SEARCH_LIBRARIES_ENV] += os.pathsep.join('reach_ros_plugins') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# REACH ROS Python | ||
|
||
This package also provides a Python interface that allows executing the ROS 2 based plugins from Python. | ||
|
||
REACH uses a ROS node singleton to allow all plugins to share the same node. | ||
For this to work, it is necessary to initialize ROS and to provide the parameters to the node. | ||
Since the node is written in C++, the `rclpy` methods can not be used. | ||
Instead, the Python interface provides methods to initialize ROS with any given command line arguments and to manually handle the parameters of the node. | ||
|
||
## Python reach study node | ||
|
||
The [`reach_ros_node.py`](./reach_ros_node.py) script is a Python equivalent of the [c++ reach study node](../src/reach_study_node.cpp). | ||
To test it out, first modify the name of the executable launched in [`start.launch.py`](../launch/start.launch.py): | ||
|
||
```diff | ||
Node( | ||
package='reach_ros', | ||
- executable='reach_ros_node', | ||
+ executable='reach_ros_node.py', | ||
output='screen', | ||
``` | ||
|
||
Then run the demo following the instructions [here](../demo/README.md). | ||
|
||
## Python reach study demo | ||
|
||
The [`demo.py` script](demo.py) will launch the same demo (described [here](../README.md)) but from Python. | ||
It will run the reach study two times, once with the original MoveIt IK solver parameters and once with a shorter timeout. | ||
The results are then compared. | ||
Please, also have a look into the Python code to see how this works. | ||
|
||
You can start the demo like this: | ||
``` | ||
ros2 run reach_ros demo.py | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#!/usr/bin/env python3 | ||
from reach import load, runReachStudy | ||
from reach_ros import init_ros, set_parameter, parse_yaml, set_logger_level, update_search_libraries_env | ||
|
||
from ament_index_python.packages import get_package_share_directory | ||
import os | ||
from rclpy.parameter import Parameter | ||
from rclpy.logging import LoggingSeverity | ||
import sys | ||
import xacro | ||
import yaml | ||
|
||
|
||
def main(): | ||
# initialize ROS with any parameters provided as arguments | ||
init_ros(sys.argv) | ||
|
||
# Set logger level to reduce MoveIt message spam | ||
moveit_loggers = ["moveit_ros", | ||
"moveit_kinematics_base", | ||
"moveit_rdf_loader", | ||
"moveit_robot_model"] | ||
for logger_name in moveit_loggers: | ||
try: | ||
set_logger_level(logger_name, LoggingSeverity.WARN) | ||
except: | ||
pass | ||
|
||
# Manually load the parameters necessary for running MoveIt. | ||
reach_ros_dir = get_package_share_directory('reach_ros') | ||
model_dir = os.path.join(reach_ros_dir, 'demo', 'model') | ||
|
||
# Generate the URDF string from the xacro file | ||
urdf = xacro.process(os.path.join(model_dir, 'reach_study.xacro')) | ||
|
||
# Load the SRDF | ||
with open(os.path.join(model_dir, 'reach_study.srdf'), 'r') as f: | ||
srdf = f.read() | ||
|
||
moveit_parameters = [ | ||
*parse_yaml(os.path.join(model_dir, 'kinematics.yaml'), 'robot_description_kinematics.'), | ||
*parse_yaml(os.path.join(model_dir, 'joint_limits.yaml'), 'robot_description_joint_limits.'), | ||
Parameter(name="robot_description", value=urdf), | ||
Parameter(name="robot_description_semantic", value=srdf), | ||
] | ||
|
||
for parameter in moveit_parameters: | ||
# We don't need to declare the parameters as the node allows undeclared parameters | ||
set_parameter(parameter.name, parameter.value) | ||
|
||
with open(os.path.join(reach_ros_dir, 'demo', 'config', 'reach_study.yaml'), 'r') as f: | ||
config = yaml.safe_load(f) | ||
|
||
# Update the search libraries environment variable to include the plugin library provided by this package | ||
update_search_libraries_env() | ||
|
||
# Disable the optimization steps to make this demo faster and highlight the performance difference | ||
config['optimization']['max_steps'] = 0 | ||
|
||
print("Starting first study with default kinematic parameters") | ||
save_dir = "/tmp" | ||
study_name = "study1" | ||
runReachStudy(config, study_name, save_dir, False) | ||
|
||
# Loading the study results | ||
results_1 = load(os.path.join(save_dir, study_name, 'reach.db.xml')).calculateResults() | ||
|
||
# Decrease the IK solver time and see if we still find equally good solutions | ||
set_parameter( | ||
"robot_description_kinematics.manipulator.kinematics_solver_timeout", 0.00005) | ||
|
||
print("Starting second study with decreased solver resolution.") | ||
study_name = 'study2' | ||
runReachStudy(config, study_name, save_dir, False) | ||
|
||
# Loading the study results | ||
results_2 = load(os.path.join(save_dir, study_name, 'reach.db.xml')).calculateResults() | ||
|
||
print('Both REACH studies finished') | ||
print(f'\tOriginal parameters: Score {results_1.total_pose_score:.2f}, Reached {results_1.reach_percentage:.2f}%') | ||
print(f'\tModified parameters: Score {results_2.total_pose_score:.2f}, Reached {results_2.reach_percentage:.2f}%') | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#!/usr/bin/env python3 | ||
from reach import runReachStudy | ||
from reach_ros import init_ros, get_parameter | ||
import sys | ||
from yaml import safe_load | ||
|
||
|
||
def main(): | ||
init_ros(sys.argv) | ||
|
||
with open(get_parameter('config_file'), 'r') as f: | ||
config = safe_load(f) | ||
|
||
config_name = get_parameter('config_name') | ||
results_dir = get_parameter('results_dir') | ||
|
||
print('Starting Python reach study node...') | ||
runReachStudy(config, config_name, results_dir, True) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.