Skip to content

Commit c53893d

Browse files
v1.0.0 (#3)
* Rename mr_desc_param.py script to mr_desc_param * Add command line args to mr_desc_param * Tool now takes a dict instead of kwargs * Changed Tool arg robot_namespace to namespace * Changed License holder * Improved README with more detailed usage info * Add requirements.txt file * Added ROS_PYTHON_VERSION conditionals to package dependencies * Change required version of scipy
2 parents ce7c9c1 + c3e0bff commit c53893d

File tree

11 files changed

+283
-88
lines changed

11 files changed

+283
-88
lines changed

CHANGELOG.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22
Changelog for package kinematics_from_description
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
1.0.0 (2020-04-26)
6+
------------------
7+
* Rename mr_desc_param.py script to mr_desc_param
8+
* Add command line args to mr_desc_param
9+
* Tool now takes a dict instead of kwargs
10+
* Changed Tool arg robot_namespace to namespace
11+
* Changed License holder
12+
* Improved README with more detailed usage info
13+
* Add requirements.txt file
14+
* Added ROS_PYTHON_VERSION conditionals to package dependencies
15+
* Change required version of scipy
16+
517
0.0.2 (2021-01-13)
618
------------------
719
* (`#1 <https://github.com/Interbotix/kinematics_from_description/pull/1>`_)

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
BSD 2-Clause License
22

3-
Copyright (c) 2022, Luke Schmitt
3+
Copyright (c) 2022, Trossen Robotics
44
All rights reserved.
55

66
Redistribution and use in source and binary forms, with or without

README.md

Lines changed: 103 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,73 +2,150 @@
22

33
## Overview
44

5-
This package contains a simple Python program that calculates some properties required to run parts of the [Modern Robotics Library](https://github.com/NxRLab/ModernRobotics) from a robot's URDF or robot_description parameter. Specifically, this program calculates the M and Slist parameters required by the MR inverse kinematics functions:
5+
This package contains a simple Python program that calculates some properties required to run parts of the [Modern Robotics Library](https://github.com/NxRLab/ModernRobotics) from a robot's URDF or robot_description parameter. Specifically, this program calculates the M and Slist parameters required by MR kinematics functions:
66

7-
- The **M** matrix is the position and orientation of the end effector frame when the robot is in its home position (i.e. all joints are at position 0).
8-
- The **Slist** matrix is the joint screw axes in the end effector frame when the robot is in its home position. This matrix is formatted to have each axis as a column.
7+
- The **M** matrix is the end effector configuration in SE(3) when the robot is in its home position (i.e. all joints are at position 0).
8+
- The **Slist** matrix is the joint screw axes expressed in the space frame when the robot is in its home position. This matrix is formatted to have each axis as a column.
9+
10+
Note that this package is only compatible with ROS Noetic and Python3. However, it can be used other ROS distributions by installing using the requirements.txt and using the Importing method described below.
911

1012
## Dependencies
1113

1214
The dependencies of this software package are:
1315

1416
- urdf_parser_py
1517
- numpy
16-
- scipy
18+
- scipy>=1.2.0 (for the scipy.spatial.transform module)
1719
- pyyaml
1820

19-
You can use rosdep or the setup file to install the required dependencies.
20-
21-
Note that this package is only compatible with ROS Noetic and Python3.
21+
You can use rosdep (only on Noetic), the requirements.txt file, or the setup.py script to install the required dependencies.
2222

2323
## Usage
2424

2525
You must specify three parameters before using this library:
2626

27-
- **namespace** - The namespace of the robot_description parameter and the namespace that each link will be listed under in the URDF. For example, if the robot is named "vx300s", a link may be listed like "vx300s/shoulder_link". If no namespace is used, leave this as an empty string, i.e. `''`.
27+
- **namespace** - The namespace of the robot_description parameter and the namespace that each link will be listed under in the URDF. For example, if the robot is named `vx300s`, a link may be named something like `vx300s/shoulder_link`. If no namespace is used, leave this as an empty string, i.e. `''`.
2828
- **space_frame** - The name given to the link that will serve as the location of the robot's base, or {0} link.
2929
- **body_frame** - The name given to the link that will serve as the location of the end effector.
3030

3131
There are two primary ways to use this library: importing the module, and using rosrun.
3232

3333
### Importing
3434

35-
The KinematicsFromDescription Tool can be imported into your Python3 script.
35+
The KinematicsFromDescription Tool can be imported into your Python script. The Tool accepts a single positional argument - a dictionary with the keys `space_frame`, `body_frame`, and `namespace`. See the [config file](config/config.yaml) for details.
3636

3737
```python
3838
from kinematics_from_description.kfd import KinematicsFromDescriptionTool as KFD
3939

4040
...
4141

4242
tool = KFD(
43-
space_frame="space_frame",
44-
body_frame="body_frame",
45-
robot_namespace="namespace")
43+
{
44+
space_frame: "space_frame",
45+
body_frame: "body_frame",
46+
namespace: "namespace"
47+
}
4648
tool.load_desc_from_file(filepath)
4749
tool.run()
4850
```
4951

5052
### Using rosrun
5153

52-
Since this package is catkin-ized, it can be launched using ROS.
54+
Since this package is catkin-ized, it can be launched using ROS.
5355

54-
1. Modify the [config.yaml](./config/config.yaml) file to match your description setup.
55-
2. Launch your robot's robot_description package to load the robot_description parameter into ROS' parameter server.
56-
3. Run the [mr_desc_param.py](./scripts/mr_desc_param.py) script using rosrun.
56+
#### Using a configuration file:
57+
- Modify the [config.yaml](./config/config.yaml) file to match your description setup.
58+
- Launch your robot's robot_description package to load the robot_description parameter into ROS' parameter server.
59+
- Run the [mr_desc_param](./scripts/mr_desc_param) script using rosrun, specifying the location of the config file.
5760

5861
```console
59-
$ rosrun kinematics_from_description mr_desc_param.py
62+
$ rosrun kinematics_from_description mr_desc_param -f /path/to/config.yaml
63+
64+
Loading configs from '/path/to/config.yaml'
65+
Using configs:
66+
space_frame: base_link
67+
body_frame: ee_gripper_link
68+
namespace: wx200
69+
precision: 6
70+
71+
The MR Descriptions are as follows:
6072

6173
M:
62-
[[1. 0. 0. 0.248575]
63-
[0. 1. 0. 0. ]
64-
[0. 0. 1. 0.1931 ]
65-
[0. 0. 0. 1. ]]
74+
array([[1. , 0. , 0. , 0.408575],
75+
[0. , 1. , 0. , 0. ],
76+
[0. , 0. , 1. , 0.31065 ],
77+
[0. , 0. , 0. , 1. ]])
6678

6779
Slist:
68-
[[ 0. 0. 1. 0. 0. 0. ]
69-
[ 0. 1. 0. -0.0931 0. 0. ]
70-
[ 0. 1. 0. -0.1931 0. 0.035 ]
71-
[ 0. 1. 0. -0.1931 0. 0.135 ]]
80+
array([[ 0. , 0. , 1. , 0. , 0. , 0. ],
81+
[ 0. , 1. , 0. , -0.11065, 0. , 0. ],
82+
[ 0. , 1. , 0. , -0.31065, 0. , 0.05 ],
83+
[ 0. , 1. , 0. , -0.31065, 0. , 0.25 ],
84+
[ 1. , 0. , 0. , 0. , 0.31065, 0. ]]).T
85+
86+
Paste these arrays into your mr_descriptions.py file to use in the Interbotix Python-ROS API.
87+
```
88+
89+
#### Using command line arguments.
90+
- Specify the `namespace`, `body_frame`, and `space_frame` configs from the command line.
91+
92+
```console
93+
$ rosrun kinematics_from_description mr_desc_param -n wx200 -b ee_gripper_link -s base_link -p 6
94+
95+
Using configs:
96+
space_frame: base_link
97+
body_frame: ee_gripper_link
98+
namespace: wx200
99+
precision: 6
100+
101+
The MR Descriptions are as follows:
102+
103+
M:
104+
array([[1. , 0. , 0. , 0.408575],
105+
[0. , 1. , 0. , 0. ],
106+
[0. , 0. , 1. , 0.31065 ],
107+
[0. , 0. , 0. , 1. ]])
108+
109+
Slist:
110+
array([[ 0. , 0. , 1. , 0. , 0. , 0. ],
111+
[ 0. , 1. , 0. , -0.11065, 0. , 0. ],
112+
[ 0. , 1. , 0. , -0.31065, 0. , 0.05 ],
113+
[ 0. , 1. , 0. , -0.31065, 0. , 0.25 ],
114+
[ 1. , 0. , 0. , 0. , 0.31065, 0. ]]).T
115+
116+
Paste these arrays into your mr_descriptions.py file to use in the Interbotix Python-ROS API.
117+
```
118+
119+
See usage details with the `-h` flag.
120+
```console
121+
$ rosrun kinematics_from_description mr_desc_param -h
122+
123+
usage: mr_desc_param [-h] [--file FILE] [--space_frame SPACE_FRAME]
124+
[--body_frame BODY_FRAME] [--namespace NAMESPACE]
125+
[--precision PRECISION]
126+
127+
A program that will parse a robot's kinematic properties from its
128+
`/robot_description` rosparam.
129+
130+
optional arguments:
131+
-h, --help show this help message and exit
132+
--file FILE, -f FILE The path to the config file to use.
133+
--space_frame SPACE_FRAME, -s SPACE_FRAME
134+
The name given to the link that will serve as the
135+
location of the robot's base, or {0} link. This is
136+
typically `base_link`.
137+
--body_frame BODY_FRAME, -b BODY_FRAME
138+
The name given to the link that will serve as the
139+
location of the end effector. This is typically
140+
`ee_gripper_link`.
141+
--namespace NAMESPACE, -n NAMESPACE
142+
The namespace under which the `/robot_description`
143+
rosparam will be found, as well as the names of each
144+
link (i.e. `/namespace/robot_description`, and
145+
`namespace/base_link`. (default: )
146+
--precision PRECISION, -p PRECISION
147+
The precision with which to print the kinematic
148+
properties. (default: 6)
72149
```
73150

74151
## Contributors
@@ -79,5 +156,4 @@ Slist:
79156

80157
- Include other useful variables like Blist
81158
- Allow for joint types other than revolute
82-
- Incorporate error handling
83-
- Improve robustness
159+
- Allow for different rosparam and joint namespaces

config/config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1+
# The namespace under which the `/robot_description` rosparam will be found, as well as
2+
# the names of each link (i.e. `/namespace/robot_description`, and `namespace/base_link`).
13
namespace: ''
4+
5+
# The name given to the link that will serve as the location of the robot's base, or {0} link.
26
space_frame: ''
7+
8+
# The name given to the link that will serve as the location of the end effector.
39
body_frame: ''
10+
11+
# The precision with which to print the kinematic properties.
412
precision: 6

package.xml

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
11
<?xml version="1.0"?>
22
<package format="3">
33
<name>kinematics_from_description</name>
4-
<version>0.0.2</version>
4+
<version>1.0.0</version>
55
<description>This package contains a simple Python program that calculates properties required to run parts of the <a href="https://github.com/NxRLab/ModernRobotics">Modern Robotics Library</a> from a robot's robot_description parameter.</description>
66

77
<license>BSD</license>
88

9-
<author email="luke@trossenrobotics.com">Luke Schmitt</author>
9+
<author email="trsupport@trossenrobotics.com">Luke Schmitt</author>
1010
<maintainer email="trsupport@trossenrobotics.com">Luke Schmitt</maintainer>
1111

12-
<url type="website">https://github.com/LSinterbotix/kinematics_from_description</url>
13-
<url type="bugtracker">https://github.com/LSinterbotix/kinematics_from_description/issues</url>
14-
<url type="repository">https://github.com/LSinterbotix/kinematics_from_description</url>
12+
<url type="website">https://github.com/Interbotix/kinematics_from_description</url>
13+
<url type="bugtracker">https://github.com/Interbotix/kinematics_from_description/issues</url>
14+
<url type="repository">https://github.com/Interbotix/kinematics_from_description</url>
1515

1616
<buildtool_depend>catkin</buildtool_depend>
17-
<buildtool_depend>python3-setuptools</buildtool_depend>
17+
<buildtool_depend condition="$ROS_PYTHON_VERSION==2">python-setuptools</buildtool_depend>
18+
<buildtool_depend condition="$ROS_PYTHON_VERSION==3">python3-setuptools</buildtool_depend>
1819

1920
<exec_depend>rospy</exec_depend>
2021
<exec_depend>urdfdom_py</exec_depend>
21-
<exec_depend>python3-yaml</exec_depend>
22-
<exec_depend>python3-numpy</exec_depend>
23-
<exec_depend version_gte="1.4.0">python3-scipy</exec_depend>
24-
22+
<exec_depend condition="$ROS_PYTHON_VERSION==2">python-yaml</exec_depend>
23+
<exec_depend condition="$ROS_PYTHON_VERSION==2">python-numpy</exec_depend>
24+
<exec_depend condition="$ROS_PYTHON_VERSION==2" version_gte="1.2.0">python-scipy</exec_depend>
25+
<exec_depend condition="$ROS_PYTHON_VERSION==3">python3-yaml</exec_depend>
26+
<exec_depend condition="$ROS_PYTHON_VERSION==3">python3-numpy</exec_depend>
27+
<exec_depend condition="$ROS_PYTHON_VERSION==3" version_gte="1.2.0">python3-scipy</exec_depend>
28+
2529
<build_depend>rostest</build_depend>
2630

2731
</package>

requirements.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# $ python -m pip install -r requirements.txt
2+
# $ python3 -m pip3 install -r requirements.txt
3+
4+
urdf_parser_py
5+
numpy
6+
scipy>=1.2.0
7+
pyyaml

scripts/mr_desc_param

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import yaml
5+
import os
6+
import numpy as np
7+
import rospkg
8+
from kinematics_from_description.kfd import KinematicsFromDescriptionTool as KFD
9+
10+
PKG = 'kinematics_from_description'
11+
12+
def main(args):
13+
if args.file is not None:
14+
filepath = os.path.join(
15+
rospkg.RosPack().get_path(PKG),
16+
'config',
17+
'config.yaml'
18+
)
19+
print("Loading configs from '%s'" % filepath)
20+
try:
21+
with open(filepath) as config_file:
22+
config = yaml.safe_load(config_file)
23+
except yaml.YAMLError as e:
24+
print(e)
25+
exit(1)
26+
elif args.space_frame is not None and args.body_frame is not None:
27+
config={}
28+
config['space_frame']=args.space_frame
29+
config['body_frame']=args.body_frame
30+
config['namespace']=args.namespace
31+
config['precision']=args.precision
32+
else:
33+
raise ValueError(
34+
'Either a file must be specified or the space and body frames must be specified.'
35+
'Use the --help flag for details.'
36+
)
37+
38+
np.set_printoptions(precision=int(config["precision"]), suppress=True)
39+
40+
print('Using configs:')
41+
print('\tspace_frame: %s' % config['space_frame'])
42+
print('\tbody_frame: %s' % config['body_frame'])
43+
print('\tnamespace: %s' % config['namespace'])
44+
print('\tprecision: %i' % config['precision'])
45+
46+
tool = KFD(config)
47+
48+
tool.load_desc_from_param()
49+
tool.run()
50+
51+
print('\nThe MR Descriptions are as follows:')
52+
53+
print("\nM:")
54+
print(repr(tool.get_M()))
55+
56+
print("\nSlist:")
57+
print(str(repr(tool.get_Slist(transposed=False))) + ".T\n")
58+
59+
print(
60+
(
61+
'Paste these arrays into your mr_descriptions.py file to use in the Interbotix '
62+
'Python-ROS API.'
63+
)
64+
)
65+
66+
67+
if __name__ == "__main__":
68+
parser = argparse.ArgumentParser(
69+
description=(
70+
"A program that will parse a robot's kinematic properties from its "
71+
'`/robot_description` rosparam.'
72+
)
73+
)
74+
parser.add_argument(
75+
'--file',
76+
'-f',
77+
type=str,
78+
help='The path to the config file to use.',
79+
)
80+
parser.add_argument(
81+
'--space_frame',
82+
'-s',
83+
type=str,
84+
help=(
85+
"The name given to the link that will serve as the location of the robot's base, or "
86+
"{0} link. This is typically `base_link`."
87+
),
88+
)
89+
parser.add_argument(
90+
'--body_frame',
91+
'-b',
92+
type=str,
93+
help=(
94+
'The name given to the link that will serve as the location of the end effector. This'
95+
' is typically `ee_gripper_link`.'
96+
),
97+
)
98+
parser.add_argument(
99+
'--namespace',
100+
'-n',
101+
type=str,
102+
default='',
103+
help=(
104+
'The namespace under which the `/robot_description` rosparam will be found, as well as'
105+
' the names of each link (i.e. `/namespace/robot_description`, and '
106+
'`namespace/base_link`. (default: %(default)s)'
107+
),
108+
)
109+
parser.add_argument(
110+
'--precision',
111+
'-p',
112+
type=int,
113+
help='The precision with which to print the kinematic properties. (default: %(default)s)',
114+
default=6,
115+
)
116+
main(args=parser.parse_args())

0 commit comments

Comments
 (0)