Skip to content

Commit 22ee97a

Browse files
Support franka panda robot.
1 parent 76bc78d commit 22ee97a

File tree

9 files changed

+739
-0
lines changed

9 files changed

+739
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ INSTALL(FILES
7979
INSTALL(FILES
8080
config/sot_params_common.yaml
8181
config/sot_params_ur.yaml
82+
config/sot_params_franka_panda.yaml
8283
DESTINATION share/${PROJECT_NAME}/config)
8384

8485
# Install default URDF file

config/sot_params_franka_panda.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
sot_controller:
2+
control_mode:
3+
panda_joint1:
4+
ros_control_mode: POSITION
5+
sot_control_mode: VELOCITY
6+
panda_joint2:
7+
ros_control_mode: POSITION
8+
sot_control_mode: VELOCITY
9+
panda_joint3:
10+
ros_control_mode: POSITION
11+
sot_control_mode: VELOCITY
12+
panda_joint4:
13+
ros_control_mode: POSITION
14+
sot_control_mode: VELOCITY
15+
panda_joint5:
16+
ros_control_mode: POSITION
17+
sot_control_mode: VELOCITY
18+
panda_joint6:
19+
ros_control_mode: POSITION
20+
sot_control_mode: VELOCITY
21+
panda_joint7:
22+
ros_control_mode: POSITION
23+
sot_control_mode: VELOCITY
24+
25+
joint_names:
26+
[$(arg arm_id)_joint1, $(arg arm_id)_joint2, $(arg arm_id)_joint3,
27+
$(arg arm_id)_joint4, $(arg arm_id)_joint5, $(arg arm_id)_joint6,
28+
$(arg arm_id)_joint7]
29+
joints:
30+
[$(arg arm_id)_joint1, $(arg arm_id)_joint2, $(arg arm_id)_joint3,
31+
$(arg arm_id)_joint4, $(arg arm_id)_joint5, $(arg arm_id)_joint6,
32+
$(arg arm_id)_joint7]
33+
sot:
34+
state_vector_map:
35+
[$(arg arm_id)_joint1, $(arg arm_id)_joint2, $(arg arm_id)_joint3,
36+
$(arg arm_id)_joint4, $(arg arm_id)_joint5, $(arg arm_id)_joint6,
37+
$(arg arm_id)_joint7]

launch/sot_params.launch

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,20 @@
1111
0.01
1212
</rosparam>
1313
</group>
14+
<group ns="sot_controller" if="$(eval robot == 'franka')">
15+
<rosparam param="dt" if="$(arg simulation)">
16+
0.001
17+
</rosparam>
18+
<rosparam param="dt" unless="$(arg simulation)">
19+
0.01
20+
</rosparam>
21+
</group>
1422
<!-- Sot Controller configuration -->
1523
<rosparam command="load"
1624
file="$(find sot_universal_robot)/config/sot_params_common.yaml"/>
25+
<rosparam command="load" if="$(eval robot == 'franka')"
26+
file="$(find sot_universal_robot)/config/sot_params_franka_$(arg arm_id).yaml"
27+
subst_value="true"/>
1728
<rosparam command="load" if="$(eval robot == 'ur')"
1829
file="$(find sot_universal_robot)/config/sot_params_ur.yaml"/>
1930
</launch>

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ DYNAMIC_GRAPH_PYTHON_MODULE("sot/robot_arm/${PYTHON_LIBRARY_NAME}"
4242
# Install Python files.
4343
SET(PYTHON_MODULE dynamic_graph/sot/robot_arm)
4444
PYTHON_INSTALL_ON_SITE("${PYTHON_MODULE}" "__init__.py")
45+
PYTHON_INSTALL_ON_SITE("${PYTHON_MODULE}" "franka.py")
4546
PYTHON_INSTALL_ON_SITE("${PYTHON_MODULE}" "prologue.py")
4647
PYTHON_INSTALL_ON_SITE("${PYTHON_MODULE}" "robot_arm.py")
4748
PYTHON_INSTALL_ON_SITE("${PYTHON_MODULE}" "universal_robot.py")

src/device-python.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ BOOST_PYTHON_MODULE(wrap)
99

1010
dynamicgraph::python::exposeEntity<SoTRobotArmDevice,
1111
bp::bases<dg::sot::Device> >();
12+
dynamicgraph::python::exposeEntity<DeviceToDynamic,
13+
bp::bases<dg::Entity> >();
1214
}

src/device.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#define ENABLE_RT_LOG
2727
#include "device.hh"
28+
#include <dynamic-graph/entity.h>
2829
#include <dynamic-graph/factory.h>
2930
#include <dynamic-graph/all-commands.h>
3031
#include <dynamic-graph/real-time-logger.h>
@@ -268,3 +269,5 @@ void SoTRobotArmDevice::integrate(const double &dt)
268269
CHECK_BOUNDS(state_, lowerPosition_, upperPosition_, "position");
269270
}
270271
}
272+
273+
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(DeviceToDynamic, "DeviceToDynamic");

src/device.hh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,31 @@ protected:
9696
dynamicgraph::Vector d_gains_;
9797
}; // class SoTRobotArmDevice
9898

99+
/// Entity that converts a vector of dimension 7 to a vector of dimension 8
100+
///
101+
/// Useful for Franka robot where device.state is of dimension 7 while
102+
/// dynamic.position expects a vector of dimension 8.
103+
/// The last component is set to 0
104+
class DeviceToDynamic : public dynamicgraph::Entity
105+
{
106+
public:
107+
static const std::string CLASS_NAME;
108+
DeviceToDynamic(const std::string& name) :
109+
dynamicgraph::Entity(name), sinSIN(0x0, "DeviceToDynamic("+name+")::input(vector)::sin"),
110+
soutSOUT(boost::bind(&DeviceToDynamic::compute, this, _1, _2),
111+
sinSIN, "DeviceToDynamic("+name+")::ouput(vector)::sout")
112+
{
113+
signalRegistration(sinSIN << soutSOUT);
114+
}
115+
private:
116+
dynamicgraph::Vector& compute(dynamicgraph::Vector& res, int time)
117+
{
118+
res.head<7>() = sinSIN(time);
119+
res[7] = 0;
120+
return res;
121+
}
122+
dynamicgraph::SignalPtr<dynamicgraph::Vector, int> sinSIN;
123+
dynamicgraph::SignalTimeDependent<dynamicgraph::Vector, int> soutSOUT;
124+
};
125+
99126
#endif // SOT_UNIVERSAL_ROBOT_DEVICE_HH
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright, 2022 CNRS
2+
# Author: Florent Lamiraux
3+
#
4+
# Redistribution and use in source and binary forms, with or without
5+
# modification, are permitted provided that the following conditions are
6+
# met:
7+
8+
# 1. Redistributions of source code must retain the above copyright
9+
# notice, this list of conditions and the following disclaimer.
10+
11+
# 2. Redistributions in binary form must reproduce the above copyright
12+
# notice, this list of conditions and the following disclaimer in the
13+
# documentation and/or other materials provided with the distribution.
14+
15+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
from .robot_arm import RobotArm
28+
from .sot_robot_arm_device import DeviceToDynamic
29+
30+
class Franka(RobotArm):
31+
"""
32+
This class defines a robot of type Franka Panda with gripper
33+
"""
34+
defaultFilename = "package://sot_universal_robot/urdf/franka.urdf"
35+
36+
def __init__(self, name, device=None, tracer=None, loadFromFile=False):
37+
RobotArm.__init__(self, name, device, tracer, loadFromFile)
38+
39+
# Resize the signal from dimension 7 to 8
40+
#
41+
# self.dynamic is initialized using the URDF model containing
42+
# 9 joints: 7 for the arm, 2 for the fingers. The second finger
43+
# joint mimics the first finger joint. The dimension is therefore 8.
44+
#
45+
# self.device is initialized via ros params and contains only 7 joints.
46+
def setClosedLoop(self, closedLoop):
47+
if closedLoop:
48+
raise RuntimeError('Closed loop not possible for Franka robot.')
49+
else:
50+
d = DeviceToDynamic('d2d')
51+
plug(self.device.state, d.signal('sin'))
52+
plug(d.signal('sout'), self.dynamic.position)
53+
self.device.setClosedLoop(False)
54+
55+
## Only the 7 arm joints are actuated
56+
#
57+
# The fingers are not controlled via roscontrol.
58+
def getActuatedJoints(self):
59+
return range(0,7)

0 commit comments

Comments
 (0)