|
YARP
Yet Another Robot Platform
|
|
Go to the documentation of this file.
91 const size_t msgsize=cmd.
size();
92 int ret=IAnalogSensor::AS_ERROR;
104 for (
unsigned int i=0; i<v.
size(); i++)
136 bool ok=in.
read(connection);
137 if (!ok)
return false;
154 if (returnToSender!=
nullptr) {
155 out.
write(*returnToSender);
195 bool AnalogWrapper::createPort(
const char* name,
int rate)
197 analogSensor_p=
nullptr;
198 analogPorts.resize(1);
199 analogPorts[0].offset = 0;
200 analogPorts[0].length = -1;
201 analogPorts[0].port_name = std::string(name);
207 bool AnalogWrapper::createPorts(
const std::vector<AnalogPortEntry>& _analogPorts,
int rate)
209 analogSensor_p=
nullptr;
210 this->analogPorts=_analogPorts;
220 frame_idVec.resize(1);
221 frame_idVec.at(0) =
"";
222 rosTopicNamesVec.resize(1);
223 rosTopicNamesVec.at(0) =
"";
224 rosMsgCounterVec.resize(1);
225 rosMsgCounterVec.at(0) = 0;
233 analogSensor_p =
nullptr;
236 void AnalogWrapper::setHandlers()
238 for(
auto& analogPort : analogPorts)
240 std::string rpcPortName = analogPort.port_name;
241 rpcPortName +=
"/rpc:i";
243 handlers.push_back(ash);
247 void AnalogWrapper::removeHandlers()
260 bool AnalogWrapper::openAndAttachSubDevice(
Searchable &prop)
272 subDeviceOwned->
open(p);
274 if (!subDeviceOwned->
isValid())
280 subDeviceOwned->
view(analogSensor_p);
282 if (analogSensor_p ==
nullptr)
284 yCError(
ANALOGWRAPPER,
"Opening IAnalogSensor interface of AnalogWrapper subdevice... FAILED\n");
297 PeriodicThread::setPeriod(_rate / 1000.0);
298 return PeriodicThread::start();
305 if( (subDeviceOwned !=
nullptr) || (ownDevices ==
true) )
321 if (analog2attach.
size() != 1)
331 Idevice2attach->
view(analogSensor_p);
334 if(
nullptr == analogSensor_p)
340 PeriodicThread::setPeriod(_rate / 1000.0);
341 return PeriodicThread::start();
350 analogSensor_p =
nullptr;
351 for(
unsigned int i=0; i<analogPorts.size(); i++)
353 if(handlers[i] !=
nullptr)
354 handlers[i]->setInterface(analogSensor_p);
362 for(
unsigned int i=0; i<analogPorts.size(); i++)
364 handlers[i]->setInterface(analogSensor_p);
374 analogSensor_p =
nullptr;
375 for(
unsigned int i=0; i<analogPorts.size(); i++)
377 handlers[i]->setInterface(analogSensor_p);
383 for(
auto& analogPort : analogPorts)
386 if (!analogPort.port.open(analogPort.port_name))
405 bool AnalogWrapper::checkROSParams(
Searchable &config)
408 if(!config.
check(
"ROS") )
411 yCInfo(
ANALOGWRAPPER) <<
"No ROS group found in config file ... skipping ROS initialization.";
426 if(!rosGroup.
check(
"useROS"))
428 yCError(
ANALOGWRAPPER) << sensorId <<
" cannot find useROS parameter, mandatory when using ROS message. \n \
429 Allowed values are true, false, ROS_only";
433 std::string ros_use_type = rosGroup.
find(
"useROS").
asString();
434 if(ros_use_type ==
"false")
440 else if(ros_use_type ==
"true")
445 else if(ros_use_type ==
"only")
452 yCInfo(
ANALOGWRAPPER) << sensorId <<
"useROS parameter is set to unvalid value ('" << ros_use_type <<
"'), supported values are 'true', 'false', 'only'";
458 if(!rosGroup.
check(
"ROS_nodeName"))
460 yCError(
ANALOGWRAPPER) << sensorId <<
" cannot find ROS_nodeName parameter, mandatory when using ROS message";
468 if(!rosGroup.
check(
"ROS_topicName"))
470 yCError(
ANALOGWRAPPER) << sensorId <<
" cannot find ROS_topicName parameter, mandatory when using ROS message";
477 rosTopicNamesVec.at(0) = rosGroup.
find(
"ROS_topicName").
asString();
481 else if(rosGroup.
find(
"ROS_topicName").
isList())
486 rosTopicNamesVec.resize(rosTopicNamesBottle->
size());
487 for(
size_t i = 0; i < rosTopicNamesBottle->
size(); i++)
489 rosTopicNamesVec.at(i) = rosTopicNamesBottle->
get(i).
asString();
493 rosMsgCounterVec.resize(rosTopicNamesVec.size());
497 if (!rosGroup.
check(
"ROS_msgType"))
499 yCError(
ANALOGWRAPPER) << sensorId <<
" cannot find ROS_msgType parameter, mandatory when using ROS message";
506 if (rosMsgType ==
"geometry_msgs/WrenchStamped")
509 if (!rosGroup.
check(
"frame_id"))
511 yCError(
ANALOGWRAPPER) << sensorId <<
" cannot find frame_id parameter, mandatory when using ROS message";
518 frame_idVec.at(0) = rosGroup.
find(
"frame_id").
asString();
526 if(frame_idBottle->
size() != rosTopicNamesVec.size())
528 yCError(
ANALOGWRAPPER,
"AnalogWrapper: mismatch between the number of ros topics and frame_ids");
534 frame_idVec.resize(frame_idBottle->
size());
535 for(
size_t i = 0; i < frame_idBottle->
size(); i++)
537 frame_idVec.at(i) = frame_idBottle->
get(i).
asString();
541 if(!rosGroup.
check(
"rosOffset"))
543 yCWarning(
ANALOGWRAPPER) << sensorId <<
"cannot find rosOffset parameter, using the default offset 0 while reading analog sensor data";
552 if(!rosGroup.
check(
"rosPadding"))
554 yCWarning(
ANALOGWRAPPER) << sensorId <<
"cannot find rosPadding parameter, using the default padding 0 while reading analog sensor data";
563 else if (rosMsgType ==
"sensor_msgs/JointState")
565 std::string jointName;
567 bool oldParam =
false;
568 bool newParam =
false;
570 if(rosGroup.
check(
"joint_names"))
573 jointName =
"joint_names";
574 yCWarning(
ANALOGWRAPPER) << sensorId <<
" using DEPRECATED 'joint_names' parameter. Please use 'jointNames' instead.";
577 if(rosGroup.
check(
"jointNames"))
580 jointName =
"jointNames";
583 if(!oldParam && !newParam)
585 yCError(
ANALOGWRAPPER) << sensorId <<
" missing 'jointNames' parameter needed when broadcasting 'sensor_msgs/JointState' message type";
590 if(oldParam && newParam)
592 yCError(
ANALOGWRAPPER) << sensorId <<
" found both DEPRECATED 'joint_names' and new 'jointNames' parameters. Please remove the old 'joint_names' from your config file.";
605 int joint_names_size = jnam.
size()-1;
606 for (
int i = 0; i < joint_names_size; i++)
608 ros_joint_names.push_back(jnam.
get(i+1).
asString());
620 bool AnalogWrapper::initialize_ROS()
622 bool success =
false;
630 if(rosNode ==
nullptr)
632 yCError(
ANALOGWRAPPER) <<
" opening " << rosNodeName <<
" Node, check your yarp-ROS network configuration\n";
637 if (rosMsgType ==
"geometry_msgs/WrenchStamped")
639 rosPublisherWrenchPortVec.resize(rosTopicNamesVec.size());
641 for(
size_t i = 0; i < rosTopicNamesVec.size(); i++)
643 if(!rosPublisherWrenchPortVec.at(i).topic(rosTopicNamesVec.at(i)))
645 yCError(
ANALOGWRAPPER) <<
" opening " << rosTopicNamesVec.at(i) <<
" Topic, check your yarp-ROS network configuration\n";
651 else if (rosMsgType ==
"sensor_msgs/JointState")
653 if (!rosPublisherJointPort.
topic(rosTopicNamesVec.at(0)))
655 yCError(
ANALOGWRAPPER) <<
" opening " << rosTopicNamesVec.at(0) <<
" Topic, check your yarp-ROS network configuration\n";
665 yCInfo(
ANALOGWRAPPER) << sensorId <<
"ROS initialized successfully, node:" << rosNodeName <<
" and opened the following topics: ";
666 for(
size_t i = 0; i < rosTopicNamesVec.size(); i++)
682 yCError(
ANALOGWRAPPER) << sensorId <<
" ROS parameter are not correct, check your configuration file";
688 yCError(
ANALOGWRAPPER) << sensorId <<
" something went wrong with ROS configuration, we should never be here!!!";
701 if (!config.
check(
"period"))
703 yCError(
ANALOGWRAPPER) <<
"AnalogWrapper: missing 'period' parameter. Check you configuration file\n";
711 if (config.
check(
"deviceId"))
713 yCError(
ANALOGWRAPPER) <<
"AnalogWrapper: the parameter 'deviceId' has been removed, please use parameter 'name' instead. \n"
714 <<
"e.g. In the FT wrapper configuration files of your robot, replace '<param name=""deviceId""> left_arm </param>' \n"
715 <<
"with '/icub/left_arm/analog:o' ";
719 if (!config.
check(
"name"))
721 yCError(
ANALOGWRAPPER) <<
"AnalogWrapper: missing 'name' parameter. Check you configuration file; it must be like:\n"
722 " name: full name of the port, like /robotName/deviceId/sensorType:o";
728 setId(
"AnalogServer");
731 if(!checkROSParams(config) )
733 yCError(
ANALOGWRAPPER) << sensorId <<
"ROS parameter are not correct, check your configuration file";
737 if(!initialize_YARP(config) )
743 if(!initialize_ROS() )
751 if(config.
check(
"subdevice"))
754 if(! openAndAttachSubDevice(config))
763 if(!openDeferredAttach(config))
784 if(!params.
check(
"ports"))
787 if (Network::exists(streamingPortName +
"/rpc:i") || Network::exists(streamingPortName))
792 createPort((streamingPortName ).c_str(), _rate );
794 if(! Network::exists(streamingPortName +
"/rpc:i"))
801 Value &deviceChannels = params.
find(
"channels");
802 if (deviceChannels.
isNull())
808 int nports=ports->
size();
809 int sumOfChannels = 0;
810 std::vector<AnalogPortEntry> tmpPorts;
811 tmpPorts.resize(nports);
813 for(
size_t k=0; k<ports->
size(); k++)
817 if (parameters.
size()!=5)
819 yCError(
ANALOGWRAPPER) <<
"AnalogWrapper: check skin port parameters in part description, I was expecting "
820 << ports->
get(k).
asString().c_str() <<
" followed by four integers";
825 if (Network::exists(streamingPortName +
"/" +
string(ports->
get(k).
asString()) +
"/rpc:i")
826 || Network::exists(streamingPortName +
"/" +
string(ports->
get(k).
asString())))
839 if(wTop-wBase != top-base){
841 << ports->
get(k).
asString().c_str() <<
" port parameters in part description";
844 int portChannels = top-base+1;
846 tmpPorts[k].length = portChannels;
847 tmpPorts[k].offset = wBase;
849 tmpPorts[k].port_name = streamingPortName+
"/" + string(ports->
get(k).
asString());
851 sumOfChannels+=portChannels;
853 createPorts(tmpPorts, _rate);
855 if (sumOfChannels!=deviceChannels.
asInt32())
857 yCError(
ANALOGWRAPPER) <<
"AnalogWrapper: Total number of mapped taxels does not correspond to total taxels";
868 for(
auto& analogPort : analogPorts)
870 analogPort.port.interrupt();
871 analogPort.port.close();
877 int first, last,
ret;
879 if (analogSensor_p!=
nullptr)
881 ret=analogSensor_p->
read(lastDataRead);
885 if (lastDataRead.
size()>0)
891 for(
auto& analogPort : analogPorts)
894 first = analogPort.offset;
895 if(analogPort.length == -1)
896 last = lastDataRead.
size()-1;
898 last = analogPort.offset + analogPort.length - 1;
901 if(last>=(
int)lastDataRead.
size()){
902 yCError(
ANALOGWRAPPER, )<<
"AnalogWrapper: error while sending analog sensor output on port "<< analogPort.port_name
903 <<
" Vector size expected to be at least "<<last<<
" whereas it is "<< lastDataRead.
size();
906 pv = lastDataRead.
subVector(first, last);
908 analogPort.port.setEnvelope(lastStateStamp);
909 analogPort.port.write();
913 if (useROS !=
ROS_disabled && rosMsgType ==
"geometry_msgs/WrenchStamped")
915 std::vector<yarp::rosmsg::geometry_msgs::WrenchStamped> rosDataVec;
916 rosDataVec.resize(rosPublisherWrenchPortVec.size());
918 for(
size_t i = 0; i < rosDataVec.size(); i++)
920 rosDataVec.at(i).header.seq = rosMsgCounterVec.at(i)++;
922 rosDataVec.at(i).header.frame_id = frame_idVec.at(i);
924 rosDataVec.at(i).wrench.force.x = lastDataRead[(rosOffset + 6 + rosPadding) * i + 0];
925 rosDataVec.at(i).wrench.force.y = lastDataRead[(rosOffset + 6 + rosPadding) * i + 1];
926 rosDataVec.at(i).wrench.force.z = lastDataRead[(rosOffset + 6 + rosPadding) * i + 2];
928 rosDataVec.at(i).wrench.torque.x = lastDataRead[(rosOffset + 6 + rosPadding) * i + 3];
929 rosDataVec.at(i).wrench.torque.y = lastDataRead[(rosOffset + 6 + rosPadding) * i + 4];
930 rosDataVec.at(i).wrench.torque.z = lastDataRead[(rosOffset + 6 + rosPadding) * i + 5];
932 rosPublisherWrenchPortVec.at(i).write(rosDataVec.at(i));
935 else if (useROS !=
ROS_disabled && rosMsgType ==
"sensor_msgs/JointState")
938 size_t data_size = lastDataRead.
size();
939 rosData.
name.resize(data_size);
942 rosData.
effort.resize(data_size);
944 if (data_size != ros_joint_names.size())
946 yCDebug(
ANALOGWRAPPER) <<
"Invalid jointNames size:" << data_size <<
"!=" << ros_joint_names.size();
950 for (
size_t i = 0; i< data_size; i++)
955 rosData.
name[i] = ros_joint_names[i];
962 rosData.
header.
seq = rosMsgCounterVec.at(0)++;
964 rosPublisherJointPort.
write(rosData);
969 yCError(
ANALOGWRAPPER,
"AnalogWrapper: %s: vector size non valid: %lu", sensorId.c_str(),
static_cast<unsigned long> (lastDataRead.
size()));
976 case IAnalogSensor::AS_OVF:
979 case IAnalogSensor::AS_TIMEOUT:
982 case IAnalogSensor::AS_ERROR:
994 if (PeriodicThread::isRunning())
996 PeriodicThread::stop();
1004 subDeviceOwned->
close();
1005 delete subDeviceOwned;
1006 subDeviceOwned =
nullptr;
1009 if(rosNode!=
nullptr) {
void close() override
Stop port activity.
A simple collection of objects that can be described and transmitted in a portable way.
virtual std::int32_t asVocab() const
Get vocabulary identifier as an integer.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
void clear()
Empties the bottle of any objects it contains.
void resize(size_t size) override
Resize the vector.
A base class for nested structures that can be searched.
bool read(ImageOf< PixelRgb > &dest, const std::string &src, image_fileformat format=FORMAT_ANY)
size_type size() const
Gets the number of elements in the bottle.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
#define yCWarning(component,...)
virtual std::string toString() const =0
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.
bool isValid() const
Check if device is valid.
virtual int calibrateSensor()=0
Calibrates the whole sensor.
~AnalogWrapper() override
#define YARP_LOG_COMPONENT(name,...)
yarp::os::BufferedPort< yarp::sig::Vector > port
double convertDegreesToRadians(double degrees)
convert degrees to radiants for ROS messages
bool threadInit() override
Initialization method.
AnalogPortEntry()
A yarp port that output data read from an analog sensor.
bool view(T *&x)
Get an interface to the device driver.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
std::vector< yarp::conf::float64_t > effort
define control board standard interfaces
bool open(const std::string &txt)
Construct and configure a device by its common name.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
double now()
Return the current time in seconds, relative to an arbitrary starting point.
An interface for the device drivers.
bool detachAll() override
Detach the object (you must have first called attach).
bool _handleIAnalog(yarp::os::Bottle &cmd, yarp::os::Bottle &reply)
A mini-server for network communication.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
bool attachAll(const yarp::dev::PolyDriverList &p) override
Specify which analog sensor this thread has to read from.
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
virtual bool isString() const
Checks if value is a string.
virtual int read(yarp::sig::Vector &out)=0
Read a vector from the sensor.
bool topic(const std::string &name)
Set topic to publish to.
std::vector< yarp::conf::float64_t > velocity
virtual int calibrateChannel(int ch)=0
Calibrates one single channel.
Interface implemented by all objects that can read themselves from the network, such as Bottle object...
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
bool close() override
Close the DeviceDriver.
void write(bool forceStrict=false)
Write the current object being returned by Publisher::prepare.
bool write(ConnectionWriter &writer) const override
Output a representation of the bottle to a network connection.
AnalogPortEntry & operator=(const AnalogPortEntry &alt)
An interface for writing to a network connection.
void setId(const std::string &id)
static void handler(int sig)
virtual std::string asString() const
Get string value.
A container for a device driver.
constexpr yarp::conf::vocab32_t VOCAB_FAILED
bool close() override
Close the DeviceDriver.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
bool setPeriod(double period)
Set the (new) period of the thread.
void threadRelease() override
Release method.
bool isNull() const override
Checks if the object is invalid.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
void run() override
Loop function.
void addInt32(std::int32_t x)
Places a 32-bit integer in the bottle, at the end of the list.
yarp::rosmsg::std_msgs::Header header
A yarp port that output data read from an analog sensor.
A generic interface to sensors (gyro, a/d converters).
virtual ConnectionWriter * getWriter()=0
Gets a way to reply to the message, if possible.
void setReader(PortReader &reader) override
Set an external reader for port data.
An abstraction for a periodic thread.
void addVocab(int x)
Places a vocabulary item in the bottle, at the end of the list.
virtual bool isList() const
Checks if value is a list.
bool isNull() const override
Checks if the object is invalid.
An interface for reading from a network connection.
void attach(yarp::dev::IAnalogSensor *s)
#define yCError(component,...)
virtual std::int32_t asInt32() const
Get 32-bit integer value.
void update()
Set the timestamp to the current time, and increment the sequence number (wrapping to 0 if the sequen...
#define yCInfo(component,...)
An interface to the operating system, including Port based communication.
#define yCDebug(component,...)
bool open(yarp::os::Searchable ¶ms) override
Open the DeviceDriver.
#define DEFAULT_THREAD_PERIOD
The main, catch-all namespace for YARP.
std::vector< std::string > name
Handler of the rpc port related to an analog sensor.
bool read(ConnectionReader &reader) override
Set the bottle's value based on input from a network connection.
virtual Bottle * asList() const
Get list value.
void interrupt()
interrupt delegates the call to the Node port interrupt.
bool read(yarp::os::ConnectionReader &connection) override
Read this object from a network connection.
void setInterface(yarp::dev::IAnalogSensor *is)
virtual int getChannels()=0
Get the number of channels of the sensor.
AnalogServerHandler(const char *n)
Handler of the rpc port related to an analog sensor.
#define yCTrace(component,...)
const yarp::os::LogComponent & ANALOGWRAPPER()
A single value (typically within a Bottle).
std::vector< yarp::conf::float64_t > position
constexpr yarp::conf::vocab32_t VOCAB_IANALOG
void unput(const std::string &key)
Remove the association from the given key to a value, if present.
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
VectorOf< T > subVector(unsigned int first, unsigned int last) const
Creates and returns a new vector, being the portion of the original vector defined by the first and l...
constexpr yarp::conf::vocab32_t VOCAB_CALIBRATE_CHANNEL
A class for storing options and configuration information.
constexpr yarp::conf::vocab32_t VOCAB_CALIBRATE
virtual bool isInt32() const
Checks if value is a 32-bit integer.