Skip to content

Commit c35ed10

Browse files
Update to modification in the way the control graph is now implemented.
Integration of the velocity is now extracted from the device and performed by an integrator class. The integration time is provided by the signal time (in microseconds).
1 parent a91c39b commit c35ed10

File tree

11 files changed

+134
-127
lines changed

11 files changed

+134
-127
lines changed

src/controller.cc

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ void workThread(SoTRobotArmController *controller)
6464
}
6565

6666
SoTRobotArmController::SoTRobotArmController():
67-
device_(new SoTRobotArmDevice("RobotArm"))
67+
device_(new SoTRobotArmDevice("RobotArm")), pythonInitialized_(false)
6868
{
6969
// Create thread and python interpreter
7070
init();
@@ -85,14 +85,14 @@ SoTRobotArmController::SoTRobotArmController():
8585
}
8686

8787
SoTRobotArmController::SoTRobotArmController(std::string RobotName):
88-
device_(new SoTRobotArmDevice (RobotName))
88+
device_(new SoTRobotArmDevice (RobotName)), pythonInitialized_(false)
8989
{
9090
// Create thread and python interpreter
9191
init();
9292
}
9393

9494
SoTRobotArmController::SoTRobotArmController(const char robotName[]):
95-
device_(new SoTRobotArmDevice (robotName))
95+
device_(new SoTRobotArmDevice (robotName)), pythonInitialized_(false)
9696
{
9797
// Create thread and python interpreter
9898
init();
@@ -110,10 +110,38 @@ SoTRobotArmController::~SoTRobotArmController()
110110
{
111111
}
112112

113+
void SoTRobotArmController::setControlSize(const int& size)
114+
{
115+
device_->setControlSize(size);
116+
}
117+
118+
// Initialize the size of the signal plugged into device.control.
119+
// The size is not known when creating python interpreter. For this reason,
120+
// we need to run the following python lines later on.
121+
//
122+
// After calling this method,
123+
// - the input velocity of the integrator is set to 0,
124+
// - the output configuration of the integrator is computed for time 0,
125+
// it contains the initial configuration of the robot as read from the joint
126+
// encoders.
127+
void SoTRobotArmController::initializePython()
128+
{
129+
std::ofstream aof(LOG_PYTHON.c_str(), std::ios::app);
130+
runPython(aof,"robot.initializeEntities()", *interpreter_);
131+
aof.close();
132+
}
133+
134+
113135
void SoTRobotArmController::setupSetSensors
114136
(map<string,SensorValues> &SensorsIn)
115137
{
116138
device_->setupSetSensors(SensorsIn);
139+
// Finish initialization of python after reading the sensors to know the
140+
// configuration of the robot.
141+
if (!pythonInitialized_) {
142+
initializePython();
143+
pythonInitialized_ = true;
144+
}
117145
}
118146

119147

src/controller.hh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ class SoTRobotArmController: public AbstractSotExternalInterface
6262
void setNoIntegration(void);
6363
void setSecondOrderIntegration(void);
6464

65+
// Set the number of joints that are controlled
66+
virtual void setControlSize(const int& size);
67+
68+
// Run some python commands that cannot be run at construction
69+
virtual void initializePython();
70+
6571
/// Embedded python interpreter accessible via Corba/ros
6672
shared_ptr<dynamicgraph::Interpreter> interpreter_;
6773

@@ -79,6 +85,8 @@ class SoTRobotArmController: public AbstractSotExternalInterface
7985
void init();
8086

8187
SoTRobotArmDevice* device_;
88+
// Whether python space has been fully initialized
89+
bool pythonInitialized_;
8290
}; // class SoTRobotArmController
8391

8492
#endif // SOT_UNIVERSAL_ROBOT_CONTROLLER_HH

src/device-python.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ BOOST_PYTHON_MODULE(wrap)
1010
dynamicgraph::python::exposeEntity<SoTRobotArmDevice,
1111
bp::bases<dg::sot::Device> >();
1212
dynamicgraph::python::exposeEntity<DeviceToDynamic,
13-
bp::bases<dg::Entity> >();
13+
bp::bases<dg::Entity> >()
14+
.def("setInputSize", &DeviceToDynamic::setInputSize);
1415
}

src/device.cc

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,6 @@ SoTRobotArmDevice::SoTRobotArmDevice(std::string RobotName):
8484
dynamicgraph::Vector data (3); data.setZero ();
8585
using namespace dynamicgraph::command;
8686
std::string docstring;
87-
/* Command increment. */
88-
docstring =
89-
"\n"
90-
" Integrate dynamics for time step provided as input\n"
91-
"\n"
92-
" take one floating point number as input\n"
93-
"\n";
94-
addCommand("increment",
95-
makeCommandVoid1((Device&)*this,
96-
&Device::increment, docstring));
97-
9887
docstring =
9988
" Set the integration in closed loop\n"
10089
"\n"
@@ -208,25 +197,6 @@ void SoTRobotArmDevice::cleanupSetSensors(map<string, SensorValues>&
208197
setSensors (SensorsIn);
209198
}
210199

211-
void SoTRobotArmDevice::getControl(map<string,ControlValues> &controlOut, const double& period)
212-
{
213-
sotDEBUGIN(25) ;
214-
std::vector<double> anglesOut;
215-
216-
// Integrate control
217-
increment(period);
218-
sotDEBUG (25) << "state = " << state_.transpose() << std::endl;
219-
previousState_ = state_;
220-
221-
// Specify the joint values for the controller.
222-
anglesOut.resize(state_.size());
223-
224-
for(unsigned int i=0; i < state_.size();++i)
225-
anglesOut[i] = state_(i);
226-
controlOut["control"].setValues(anglesOut);
227-
sotDEBUGOUT(25) ;
228-
}
229-
230200
void SoTRobotArmDevice::integrate(const double &dt)
231201
{
232202
using dynamicgraph::Vector;

src/device.hh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ public:
5858

5959
void cleanupSetSensors(std::map<std::string, SensorValues> &sensorsIn);
6060

61-
void getControl(std::map<std::string, ControlValues> &anglesOut, const double& period);
62-
6361
/// \todo this should go into the parent class, in sot-core package
6462
void setTimeStep (double dt)
6563
{
@@ -112,6 +110,10 @@ public:
112110
{
113111
signalRegistration(sinSIN << soutSOUT);
114112
}
113+
void setInputSize(const int& size)
114+
{
115+
inputSize_ = size;
116+
}
115117
private:
116118
dynamicgraph::Vector& compute(dynamicgraph::Vector& res, int time)
117119
{
@@ -121,6 +123,7 @@ private:
121123
}
122124
dynamicgraph::SignalPtr<dynamicgraph::Vector, int> sinSIN;
123125
dynamicgraph::SignalTimeDependent<dynamicgraph::Vector, int> soutSOUT;
126+
int inputSize_;
124127
};
125128

126129
#endif // SOT_UNIVERSAL_ROBOT_DEVICE_HH

src/dynamic_graph/sot/robot_arm/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,3 @@
2626
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727

2828
from .robot_arm import RobotArm
29-
from .universal_robot import UniversalRobot
30-
from .franka import Franka

src/dynamic_graph/sot/robot_arm/franka.py

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,36 +24,10 @@
2424
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2525
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626

27-
from .robot_arm import RobotArm
28-
from .sot_robot_arm_device import DeviceToDynamic
27+
from dynamic_graph.sot.dynamic_pinocchio.robot import Robot
2928

3029
class Franka(RobotArm):
3130
"""
3231
This class defines a robot of type Franka Panda with gripper
3332
"""
3433
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)

src/dynamic_graph/sot/robot_arm/prologue.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
import sys
2828

2929
from .sot_robot_arm_device import DeviceRobotArm
30-
from . import Franka
31-
from . import UniversalRobot
30+
from .robot_arm import RobotArm
3231

3332
if not hasattr(sys, 'argv'):
3433
sys.argv = [
@@ -37,16 +36,13 @@
3736

3837
print("Prologue RobotArm")
3938

40-
RobotFactory = {'ur': UniversalRobot, 'franka': Franka}
41-
4239
# Create the device.
4340
# This entity behaves exactly like robotsimu except:
4441
# 1. it does not provide the increment command
4542
# 2. it forwards the robot control to the sot-abstract
4643
# controller.
4744
def makeRobot(robotType):
48-
Robot = RobotFactory[robotType]
4945
# Create the robot using the device.
50-
robot = Robot(name=robotType, device=DeviceRobotArm('RobotArm'))
46+
robot = RobotArm(name=robotType, device=DeviceRobotArm('RobotArm'))
5147
return robot
5248

src/dynamic_graph/sot/robot_arm/robot_arm.py

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,55 +25,30 @@
2525
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2626
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727

28+
import numpy
2829
import pinocchio as se3
2930
from dynamic_graph import plug
30-
from dynamic_graph.sot.core.math_small_entities import Derivator_of_Vector
3131
from dynamic_graph.sot.dynamic_pinocchio.dynamic import DynamicPinocchio
32-
from dynamic_graph.sot.dynamic_pinocchio.humanoid_robot import AbstractRobot
32+
from dynamic_graph.sot.dynamic_pinocchio.robot import AbstractRobot
3333
import pinocchio
3434

3535
class RobotArm(AbstractRobot):
3636
"""
3737
This class defines an industrial robot arm
3838
"""
39-
40-
rosParamName = "/robot_description"
41-
def __init__(self, name, device=None, tracer=None, loadFromFile=False):
42-
self.OperationalPointsMap = None
43-
44-
if loadFromFile:
45-
print("Loading from file " + self.defaultFilename)
46-
self.loadModelFromUrdf(self.defaultFilename, rootJointType=None)
47-
else:
48-
print("Using ROS parameter \"/robot_description\"")
49-
import rospy
50-
if self.rosParamName not in rospy.get_param_names():
51-
raise RuntimeError('"' + self.rosParamName +
52-
'" is not a ROS parameter.')
53-
s = rospy.get_param(self.rosParamName)
54-
self.loadModelFromString(s, rootJointType=None)
55-
AbstractRobot.__init__(self, name, tracer)
56-
57-
# Create rigid body dynamics model and data (pinocchio)
58-
self.dynamic = DynamicPinocchio(self.name + "_dynamic")
59-
self.dynamic.setModel(self.pinocchioModel)
60-
self.dynamic.setData(self.pinocchioData)
61-
self.dynamic.displayModel()
62-
self.dimension = self.dynamic.getDimension()
63-
64-
self.device = device
65-
self.initializeRobot()
66-
67-
# Create operational points based on operational points map
68-
# (if provided)
69-
if self.OperationalPointsMap is not None:
70-
self.initializeOpPoints()
71-
72-
def defineHalfSitting(self, q):
73-
pass
74-
75-
def _initialize(self):
76-
AbstractRobot._initialize(self)
77-
self.OperationalPoints.extend(['wrist', 'gaze'])
78-
79-
__all__ = [RobotArm]
39+
# Index of the first actuated joint in the configuration vector
40+
firstJointIndex = 0
41+
def getActuatedJoints(self):
42+
return range(0, self.device.getControlSize())
43+
44+
def initializeEntities(self):
45+
# initialize size of some signals. The size is not known at construction
46+
controlSize = self.device.getControlSize()
47+
self.selector.selec(self.firstJointIndex, self.firstJointIndex +
48+
controlSize)
49+
q = numpy.zeros(self.dynamic.getDimension())
50+
q[0:controlSize] = self.device.signal("robotState").value
51+
self.integrator.setInitialConfig(q)
52+
self.integrator.signal("velocity").value = \
53+
numpy.zeros(self.pinocchioModel.nv)
54+
self.integrator.signal('configuration').recompute(0)

src/dynamic_graph/sot/robot_arm/universal_robot.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,10 @@
2424
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2525
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626

27-
from .robot_arm import RobotArm
27+
from dynamic_graph.sot.dynamic_pinocchio.robot import Robot
2828

29-
class UniversalRobot(RobotArm):
29+
class UniversalRobot(Robot):
3030
"""
3131
This class defines a robot of type UniversalRobot: UR3, UR5, UR10
3232
"""
3333
defaultFilename = "package://sot_universal_robot/urdf/ur10.urdf"
34-
35-
def __init__(self, name, device=None, tracer=None, loadFromFile=False):
36-
RobotArm.__init__(self, name, device, tracer, loadFromFile)
37-
38-
def setClosedLoop(self, closedLoop):
39-
if closedLoop:
40-
plug(self.device.robotState, self.dynamic.position)
41-
self.device.setClosedLoop(True)
42-
else:
43-
plug(self.device.state, self.dynamic.position)
44-
self.device.setClosedLoop(False)

0 commit comments

Comments
 (0)