32 streaming_parser.
init(
this);
33 RPC_parser.
init(
this);
36 void ControlBoardWrapper::cleanup_yarpPorts()
43 inputStreamingPort.interrupt();
44 inputStreamingPort.close();
47 outputPositionStatePort.
close();
50 extendedOutputStatePort.
close();
70 if (rosNode !=
nullptr) {
78 if (subDeviceOwned !=
nullptr) {
79 subDeviceOwned->
close();
80 delete subDeviceOwned;
81 subDeviceOwned =
nullptr;
89 bool ControlBoardWrapper::checkPortName(
Searchable& params)
94 if (params.
check(
"rootName")) {
96 "************************************************************************************\n"
97 "* controlboardwrapper2 is using the deprecated parameter 'rootName' for port name, *\n"
98 "* It has to be removed and substituted with: *\n"
99 "* name: full port prefix name with leading '/', e.g. /robotName/part/ *\n"
100 "************************************************************************************";
105 if (!params.
check(
"name")) {
107 "************************************************************************************\n"
108 "* controlboardwrapper2 missing mandatory parameter 'name' for port name, usage is: *\n"
109 "* name: full port prefix name with leading '/', e.g. /robotName/part/ *\n"
110 "************************************************************************************";
117 "************************************************************************************\n"
118 "* controlboardwrapper2 'name' parameter for port name does not follow convention, *\n"
119 "* it MUST start with a leading '/' since it is used as the full prefix port name *\n"
120 "* name: full port prefix name with leading '/', e.g. /robotName/part/ *\n"
121 "* A temporary automatic fix will be done for you, but please fix your config file *\n"
122 "************************************************************************************";
131 bool ControlBoardWrapper::checkROSParams(
Searchable& config)
134 if (!config.
check(
"ROS")) {
149 if (!rosGroup.
check(
"useROS")) {
151 Allowed values are true, false, ROS_only";
155 std::string ros_use_type = rosGroup.
find(
"useROS").
asString();
156 if (ros_use_type ==
"false") {
162 if (ros_use_type ==
"true") {
165 }
else if (ros_use_type ==
"only") {
169 yCInfo(
CONTROLBOARD) <<
partName <<
"useROS parameter is seet to unvalid value ('" << ros_use_type <<
"'), supported values are 'true', 'false', 'only'";
175 if (!rosGroup.
check(
"ROS_nodeName")) {
181 if(rosNodeName[0] !=
'/'){
188 if (!rosGroup.
check(
"ROS_topicName")) {
193 rosTopicName = rosGroup.
find(
"ROS_topicName").
asString();
199 if (!rosGroup.
check(
"jointNames")) {
224 bool ControlBoardWrapper::initialize_ROS()
226 bool success =
false;
232 if (rosNode ==
nullptr) {
233 yCError(
CONTROLBOARD) <<
" opening " << rosNodeName <<
" Node, check your yarp-ROS network configuration";
238 if (!rosPublisherPort.
topic(rosTopicName)) {
239 yCError(
CONTROLBOARD) <<
" opening " << rosTopicName <<
" Topic, check your yarp-ROS network configuration";
267 bool success =
false;
285 rootName = prop.
check(
"rootName",
Value(
"/"),
"starting '/' if needed.").asString();
286 partName = prop.
check(
"name",
Value(
"controlboard"),
"prefix for port names").asString();
288 if (rootName.find(
"//") != std::string::npos) {
289 rootName.replace(rootName.find(
"//"), 2,
"/");
293 if (!inputRPCPort.
open((rootName +
"/rpc:i"))) {
299 inputRPC_buffer.
attach(inputRPCPort);
300 RPC_parser.
attach(inputRPC_buffer);
302 if (!inputStreamingPort.open(rootName +
"/command:i")) {
309 inputStreamingPort.setStrict();
310 inputStreamingPort.useCallback(streaming_parser);
312 if (!outputPositionStatePort.
open(rootName +
"/state:o")) {
319 if (!extendedOutputStatePort.
open(rootName +
"/stateExt:o")) {
324 extendedOutputState_buffer.
attach(extendedOutputStatePort);
339 yCWarning(
CONTROLBOARD) <<
"The 'controlboardwrapper2' device is deprecated in favour of 'controlboardremapper' + 'controlBoard_nws_yarp'.";
340 yCWarning(
CONTROLBOARD) <<
"The old device is no longer supported, and it will be deprecated in YARP 3.6 and removed in YARP 4.";
346 if (prop.
check(
"verbose",
"Deprecated flag. Use log components instead")) {
350 if (!checkPortName(config)) {
351 yCError(
CONTROLBOARD) <<
"'portName' was not correctly set, check you r configuration file";
356 if (prop.
check(
"threadrate")) {
362 if (prop.
check(
"period")) {
374 period = default_period;
379 if (prop.
check(
"subdevice")) {
381 prop.setMonitor(config.getMonitor());
382 if (!openAndAttachSubDevice(prop)) {
388 if (!openDeferredAttach(prop)) {
398 if (!checkROSParams(config)) {
404 if (!initialize_ROS()) {
409 if (!initialize_YARP(prop)) {
423 PeriodicThread::setPeriod(period);
424 if (!PeriodicThread::start()) {
434 bool ControlBoardWrapper::openDeferredAttach(
Property& prop)
436 if (!prop.
check(
"networks",
"list of networks merged by this wrapper")) {
442 if (nets ==
nullptr) {
443 yCError(
CONTROLBOARD) <<
"Error parsing parameters: \"networks\" should be followed by a list";
447 if (!prop.
check(
"joints",
"number of joints of the part")) {
453 size_t nsubdevices = nets->
size();
459 for (
size_t k = 0; k < nets->
size(); k++) {
468 if (parameters.
size() == 2) {
471 if (bot ==
nullptr) {
476 if (tmpBot.
size() != 4) {
478 <<
"--> I was expecting " << nets->
get(k).
asString() <<
" followed by a list of four integers in parenthesis"
479 <<
"Got: " << parameters.
toString();
487 wBase =
static_cast<size_t>(bot->
get(0).
asInt32());
488 wTop =
static_cast<size_t>(bot->
get(1).
asInt32());
489 base =
static_cast<size_t>(bot->
get(2).
asInt32());
490 top =
static_cast<size_t>(bot->
get(3).
asInt32());
491 }
else if (parameters.
size() == 5) {
493 wBase =
static_cast<size_t>(parameters.
get(1).
asInt32());
494 wTop =
static_cast<size_t>(parameters.
get(2).
asInt32());
495 base =
static_cast<size_t>(parameters.
get(3).
asInt32());
496 top =
static_cast<size_t>(parameters.
get(4).
asInt32());
499 <<
"--> I was expecting " << nets->
get(k).
asString() <<
" followed by a list of four integers in parenthesis"
500 <<
"Got: " << parameters.
toString();
510 size_t axes = top - base + 1;
519 <<
"First index " << wBase <<
"must be inside range from 0 to 'joints' (" <<
controlledJoints <<
")";
525 <<
"Second index " << wTop <<
"must be inside range from 0 to 'joints' (" <<
controlledJoints <<
")";
531 <<
"First index " << wBase <<
"must be lower than second index " << wTop;
535 for (
size_t j = wBase, jInDev = base; j <= wTop; j++, jInDev++) {
537 device.
lut[j].offset =
static_cast<int>(j - wBase);
553 bool ControlBoardWrapper::openAndAttachSubDevice(
Property& prop)
559 std::string subdevice = prop.
find(
"subdevice").
asString();
560 p.setMonitor(prop.getMonitor(), subdevice.c_str());
562 p.
put(
"device", subdevice);
566 subDeviceOwned->
open(p);
568 if (!subDeviceOwned->
isValid()) {
575 subDeviceOwned->
view(iencs);
577 if (iencs ==
nullptr) {
583 bool getAx = iencs->
getAxes(&tmp_axes);
605 std::string subDevName((
partName +
"_" + subdevice));
624 calculateMaxNumOfJointsInDevices();
628 void ControlBoardWrapper::calculateMaxNumOfJointsInDevices()
640 bool ControlBoardWrapper::updateAxisName()
658 std::vector<std::string> tmpVect;
664 std::string tmp2(tmp);
665 tmpVect.push_back(tmp2);
670 if (!jointNames.empty()) {
671 yCWarning(
CONTROLBOARD) <<
"Found 2 instance of jointNames parameter: one in the wrapper [ROS] group and another one in the subdevice, the latter one will be used.";
672 std::string fullNames;
674 fullNames.append(tmpVect[i]);
679 jointNames = tmpVect;
681 if (jointNames.empty()) {
682 yCError(
CONTROLBOARD) <<
"Joint names were not found! they are mandatory when using ROS topic";
687 "************************************************************************************************** \n" <<
688 "* Joint names for ROS topic were found in the [ROS] group in the wrapper config file for\n" <<
689 "* '" <<
partName <<
"' device.\n" <<
690 "* They should be in the MotionControl device(s) instead. Please update the config files.\n" <<
691 "**************************************************************************************************";
704 for (
int p = 0; p < polylist.
size(); p++) {
706 std::string tmpKey = polylist[p]->key;
707 if (tmpKey ==
"Calibrator" || tmpKey ==
"calibrator") {
710 polylist[p]->poly->view(calibrator);
712 IRemoteCalibrator::setCalibratorDevice(calibrator);
731 if (!subdevice.isAttached()) {
732 yCError(
CONTROLBOARD,
"Device %s was not found in the list passed to attachAll", subdevice.id.c_str());
738 yCError(
CONTROLBOARD,
"AttachAll failed, some subdevice was not found or its attach failed");
739 std::stringstream ss;
740 for (
int p = 0; p < polylist.
size(); p++) {
741 ss << polylist[p]->key.c_str() <<
" ";
751 calculateMaxNumOfJointsInDevices();
752 PeriodicThread::setPeriod(period);
753 return PeriodicThread::start();
769 for (
int k = 0; k < devices; k++) {
776 IRemoteCalibrator::releaseCalibratorDevice();
783 if (inputStreamingPort.getPendingReads() >= 20) {
784 yCWarning(
CONTROLBOARD) <<
"Number of streaming input messages to be read is " << inputStreamingPort.getPendingReads() <<
" and can overflow";
807 jointData& yarp_struct = extendedOutputState_buffer.
get();
843 extendedOutputState_buffer.
write();
851 outputPositionStatePort.
write();
865 ros_struct.
name = jointNames;
870 rosPublisherPort.
write(ros_struct);
const yarp::os::LogComponent & CONTROLBOARD()
bool getJointType(int j, yarp::dev::JointTypeEnum &type) override
bool getAxisName(int j, std::string &name) override
bool getCurrents(double *currs)
bool getControlModes(int *modes) override
Get the current control mode (multiple joints).
bool getEncoderAccelerations(double *accs) override
Read the instantaneous acceleration of all axes.
bool getEncoderSpeeds(double *spds) override
Read the instantaneous speed of all axes.
bool getEncodersTimed(double *encs, double *t) override
Read the instantaneous acceleration of all axes.
bool getInteractionModes(int n_joints, int *joints, yarp::dev::InteractionModeEnum *modes) override
Get the current interaction mode of the robot for a set of joints, values can be stiff or compliant.
bool getMotorEncoderSpeeds(double *spds) override
Read the instantaneous speed of all motor encoders.
bool getMotorEncoders(double *encs) override
Read the position of all motor encoders.
bool getMotorEncoderAccelerations(double *accs) override
Read the instantaneous acceleration of all motor encoders.
bool getDutyCycles(double *v) override
Gets the current dutycycle of the output of the amplifier (i.e.
bool getTorques(double *t) override
Get the value of the torque for all joints (this is the feedback if you have torque sensors).
bool open(yarp::os::Searchable &prop) override
Open the device driver.
bool detachAll() override
Detach the object (you must have first called attach).
~ControlBoardWrapper() override
bool close() override
Close the device driver by deallocating all resources and closing ports.
void run() override
The thread main loop deals with writing on ports here.
bool attachAll(const yarp::dev::PolyDriverList &l) override
Attach to a list of objects.
void resize(int _deviceNum, int _maxJointsNumForDevice, WrappedDevice *_device)
void init(yarp::dev::DeviceDriver *x)
Initialization.
virtual bool initialize()
Initialize the internal data.
void init(yarp::dev::DeviceDriver *x)
Initialization.
bool configure(size_t wbase, size_t wtop, size_t base, size_t top, size_t axes, const std::string &id, const std::string &_parentName)
std::vector< DevicesLutEntry > lut
SubDevice * getSubdevice(size_t i)
size_t maxNumOfJointsInDevices
SubDeviceVector subdevices
bool view(T *&x)
Get an interface to the device driver.
void attach(yarp::os::TypedReader< yarp::os::Bottle > &source)
Attach this object to a source of messages.
Control board, encoder interface.
virtual bool getAxes(int *ax)=0
Get the number of controlled axes.
IRemoteCalibrator interface is meant to remotize the access of the calibration device in order to all...
A container for a device driver.
bool close() override
Close the DeviceDriver.
bool isValid() const
Check if device is valid.
bool open(const std::string &txt)
Construct and configure a device by its common name.
yarp::sig::VectorOf< double > motorVelocity
yarp::sig::VectorOf< double > jointAcceleration
yarp::sig::VectorOf< int > controlMode
bool pwmDutycycle_isValid
yarp::sig::VectorOf< int > interactionMode
yarp::sig::VectorOf< double > current
bool jointVelocity_isValid
yarp::sig::VectorOf< double > motorAcceleration
bool motorVelocity_isValid
yarp::sig::VectorOf< double > motorPosition
yarp::sig::VectorOf< double > pwmDutycycle
bool jointAcceleration_isValid
yarp::sig::VectorOf< double > torque
bool motorAcceleration_isValid
bool interactionMode_isValid
yarp::sig::VectorOf< double > jointPosition
bool motorPosition_isValid
bool jointPosition_isValid
yarp::sig::VectorOf< double > jointVelocity
A simple collection of objects that can be described and transmitted in a portable way.
void fromString(const std::string &text)
Initializes bottle from a string.
size_type size() const
Gets the number of elements in the bottle.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Bottle tail() const
Get all but the first element of a bottle.
bool isNull() const override
Checks if the object is invalid.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
void close() override
Stop port activity.
bool setEnvelope(PortWriter &envelope) override
Set an envelope (e.g., a timestamp) to the next message which will be sent.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
void interrupt() override
Interrupt any current reads or writes attached to the port.
void write(bool forceStrict=false)
Write the current object being returned by BufferedPort::prepare.
T & prepare()
Access the object which will be transmitted by the next call to yarp::os::BufferedPort::write.
An abstraction for a periodic thread.
bool isRunning() const
Returns true when the thread is started, false otherwise.
void stop()
Call this to stop the thread, this call blocks until the thread is terminated (and releaseThread() ca...
void attach(Port &port)
Attach this buffer to a particular port.
void write(bool forceStrict=false)
Try to write the last buffer returned by PortWriterBuffer::get.
T & get()
A synonym of PortWriterBuffer::prepare.
void attach(Port &port)
Set the Port to which objects will be written.
void setReader(PortReader &reader) override
Set an external reader for port data.
bool removeCallbackLock() override
Remove a lock on callbacks added with setCallbackLock()
void interrupt() override
Interrupt any current reads or writes attached to the port.
bool setEnvelope(PortWriter &envelope) override
Set an envelope (e.g., a timestamp) to the next message which will be sent.
void close() override
Stop port activity.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
A class for storing options and configuration information.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
std::string toString() const override
Return a standard text representation of the content of the object.
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
void unput(const std::string &key)
Remove the association from the given key to a value, if present.
bool topic(const std::string &name)
Set topic to publish to.
void write(bool forceStrict=false)
Write the current object being returned by Publisher::prepare.
A base class for nested structures that can be searched.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
An abstraction for a time stamp and/or sequence number.
void update()
Set the timestamp to the current time, and increment the sequence number (wrapping to 0 if the sequen...
double getTime() const
Get the time stamp.
A single value (typically within a Bottle).
virtual std::int32_t asInt32() const
Get 32-bit integer value.
virtual Bottle * asList() const
Get list value.
std::string toString() const override
Return a standard text representation of the content of the object.
virtual bool isInt32() const
Checks if value is a 32-bit integer.
virtual std::string asString() const
Get string value.
std::vector< std::string > name
std::vector< yarp::conf::float64_t > position
std::vector< yarp::conf::float64_t > velocity
std::vector< yarp::conf::float64_t > effort
yarp::rosmsg::std_msgs::Header header
void resize(size_t size) override
Resize the vector.
iterator begin() noexcept
Returns an iterator to the beginning of the VectorOf.
T * data()
Return a pointer to the first element of the vector.
iterator end() noexcept
Returns an iterator to the end of the VectorOf.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCWarning(component,...)
#define yCDebug(component,...)
An interface for the device drivers.
@ VOCAB_JOINTTYPE_REVOLUTE
An interface to the operating system, including Port based communication.
The main, catch-all namespace for YARP.
double convertDegreesToRadians(double degrees)
convert degrees to radiants for ROS messages