diff --git a/libraries/YarpPlugins/CanBusControlboard/CanBusControlboard.hpp b/libraries/YarpPlugins/CanBusControlboard/CanBusControlboard.hpp index de4d782bd..dfc6b6a2b 100644 --- a/libraries/YarpPlugins/CanBusControlboard/CanBusControlboard.hpp +++ b/libraries/YarpPlugins/CanBusControlboard/CanBusControlboard.hpp @@ -10,8 +10,6 @@ #include #include -#include - #include "ICanBusSharer.hpp" #include "PositionDirectThread.hpp" #include "DeviceMapper.hpp" @@ -19,9 +17,6 @@ #define CHECK_JOINT(j) do { int n = deviceMapper.getControlledAxes(); if ((j) < 0 || (j) > n - 1) return false; } while (0) -#define DEFAULT_MODE "position" -#define DEFAULT_CUI_TIMEOUT 1.0 -#define DEFAULT_CAN_BUS "CanBusHico" #define DEFAULT_LIN_INTERP_PERIOD_MS 50 #define DEFAULT_LIN_INTERP_BUFFER_SIZE 1 #define DEFAULT_LIN_INTERP_MODE "pt" @@ -30,8 +25,8 @@ #define DEFAULT_CAN_TX_BUFFER_SIZE 500 #define DEFAULT_CAN_RX_PERIOD_MS -1 #define DEFAULT_CAN_TX_PERIOD_MS 1.0 -#define DEFAULT_CAN_SDO_TIMEOUT_MS 25.0 -#define DEFAULT_CAN_DRIVE_STATE_TIMEOUT 2.5 +#define DEFAULT_CAN_SDO_TIMEOUT_MS 25.0 // FIXME unused +#define DEFAULT_CAN_DRIVE_STATE_TIMEOUT 2.5 // FIXME unused namespace roboticslab { @@ -322,7 +317,7 @@ class CanBusControlboard : public yarp::dev::DeviceDriver, yarp::dev::PolyDriver canBusDevice; yarp::dev::ICanBus * iCanBus; - yarp::dev::PolyDriverList nodes; + yarp::dev::PolyDriverList nodeDevices; DeviceMapper deviceMapper; std::vector iCanBusSharers; diff --git a/libraries/YarpPlugins/CanBusControlboard/DeviceDriverImpl.cpp b/libraries/YarpPlugins/CanBusControlboard/DeviceDriverImpl.cpp index 29b91c7a4..201c27463 100644 --- a/libraries/YarpPlugins/CanBusControlboard/DeviceDriverImpl.cpp +++ b/libraries/YarpPlugins/CanBusControlboard/DeviceDriverImpl.cpp @@ -2,8 +2,9 @@ #include "CanBusControlboard.hpp" -#include -#include +#include + +#include using namespace roboticslab; @@ -11,47 +12,37 @@ using namespace roboticslab; bool CanBusControlboard::open(yarp::os::Searchable & config) { - int cuiTimeout = config.check("waitEncoder", yarp::os::Value(DEFAULT_CUI_TIMEOUT), "CUI timeout (seconds)").asInt32(); + CD_DEBUG("%s\n", config.toString().c_str()); - std::string canBusType = config.check("canBusType", yarp::os::Value(DEFAULT_CAN_BUS), "CAN bus device name").asString(); - int canRxBufferSize = config.check("canBusRxBufferSize", yarp::os::Value(DEFAULT_CAN_RX_BUFFER_SIZE), "CAN bus RX buffer size").asInt(); - int canTxBufferSize = config.check("canBusTxBufferSize", yarp::os::Value(DEFAULT_CAN_TX_BUFFER_SIZE), "CAN bus TX buffer size").asInt(); - double canRxPeriodMs = config.check("canRxPeriodMs", yarp::os::Value(DEFAULT_CAN_RX_PERIOD_MS), "CAN bus RX period (milliseconds)").asFloat64(); - double canTxPeriodMs = config.check("canTxPeriodMs", yarp::os::Value(DEFAULT_CAN_TX_PERIOD_MS), "CAN bus TX period (milliseconds)").asFloat64(); - double canSdoTimeoutMs = config.check("canSdoTimeoutMs", yarp::os::Value(DEFAULT_CAN_SDO_TIMEOUT_MS), "CAN bus SDO timeout (milliseconds)").asFloat64(); - double canDriveStateTimeout = config.check("canDriveStateTimeout", yarp::os::Value(DEFAULT_CAN_DRIVE_STATE_TIMEOUT), "CAN drive state timeout (seconds)").asFloat64(); + if (!config.check("bus", "CAN bus") || !config.check("nodes", "CAN nodes")) + { + CD_ERROR("Some mandatory keys are missing: \"bus\", \"nodes\".\n"); + return false; + } - linInterpPeriodMs = config.check("linInterpPeriodMs", yarp::os::Value(DEFAULT_LIN_INTERP_PERIOD_MS), "linear interpolation mode period (milliseconds)").asInt32(); - linInterpBufferSize = config.check("linInterpBufferSize", yarp::os::Value(DEFAULT_LIN_INTERP_BUFFER_SIZE), "linear interpolation mode buffer size").asInt32(); - linInterpMode = config.check("linInterpMode", yarp::os::Value(DEFAULT_LIN_INTERP_MODE), "linear interpolation mode (pt/pvt)").asString(); + std::string canBus = config.find("bus").asString(); + yarp::os::Bottle * nodes = config.find("nodes").asList(); - yarp::os::Bottle ids = config.findGroup("ids", "CAN bus IDs").tail(); //-- e.g. 15 - yarp::os::Bottle trs = config.findGroup("trs", "reductions").tail(); //-- e.g. 160 - yarp::os::Bottle ks = config.findGroup("ks", "motor constants").tail(); //-- e.g. 0.0706 + if (canBus.empty() || nodes == nullptr) + { + CD_ERROR("Illegal key(s): empty \"bus\" or nullptr \"nodes\".\n"); + return false; + } - yarp::os::Bottle maxs = config.findGroup("maxs", "maximum joint limits (meters or degrees)").tail(); //-- e.g. 360 - yarp::os::Bottle mins = config.findGroup("mins", "minimum joint limits (meters or degrees)").tail(); //-- e.g. -360 - yarp::os::Bottle maxVels = config.findGroup("maxVels", "maximum joint velocities (meters/second or degrees/second)").tail(); //-- e.g. 1000 - yarp::os::Bottle refAccelerations = config.findGroup("refAccelerations", "ref accelerations (meters/second^2 or degrees/second^2)").tail(); //-- e.g. 0.575437 - yarp::os::Bottle refSpeeds = config.findGroup("refSpeeds", "ref speeds (meters/second or degrees/second)").tail(); //-- e.g. 737.2798 - yarp::os::Bottle encoderPulsess = config.findGroup("encoderPulsess", "encoder pulses (multiple nodes)").tail(); //-- e.g. 4096 (4 * 1024) - yarp::os::Bottle pulsesPerSamples = config.findGroup("pulsesPerSamples", "encoder pulses per sample (multiple nodes)").tail(); //-- e.g. 1000 + yarp::os::Bottle & canBusGroup = config.findGroup(canBus); - yarp::os::Bottle types = config.findGroup("types", "device name of each node").tail(); //-- e.g. 15 + if (canBusGroup.isNull()) + { + CD_ERROR("Missing CAN bus device group %s.\n", canBus.c_str()); + return false; + } yarp::os::Property canBusOptions; - canBusOptions.fromString(config.toString()); // canDevice, canBitrate - canBusOptions.put("device", canBusType); + canBusOptions.fromString(canBusGroup.toString(), false); + canBusOptions.fromString(config.toString(), false); canBusOptions.put("canBlockingMode", false); // enforce non-blocking mode canBusOptions.put("canAllowPermissive", false); // always check usage requirements - canBusOptions.setMonitor(config.getMonitor(), canBusType.c_str()); - - int parallelCanThreadLimit = config.check("parallelCanThreadLimit", yarp::os::Value(0), "parallel CAN TX thread limit").asInt32(); - - if (parallelCanThreadLimit > 0) - { - deviceMapper.enableParallelization(parallelCanThreadLimit); - } + canBusOptions.setMonitor(config.getMonitor(), canBus.c_str()); if (!canBusDevice.open(canBusOptions)) { @@ -61,7 +52,7 @@ bool CanBusControlboard::open(yarp::os::Searchable & config) if (!canBusDevice.view(iCanBus)) { - CD_ERROR("Cannot view ICanBus interface in device: %s.\n", canBusType.c_str()); + CD_ERROR("Cannot view ICanBus interface in device: %s.\n", canBus.c_str()); return false; } @@ -69,50 +60,61 @@ bool CanBusControlboard::open(yarp::os::Searchable & config) if (!canBusDevice.view(iCanBufferFactory)) { - CD_ERROR("Cannot view ICanBufferFactory interface in device: %s.\n", canBusType.c_str()); + CD_ERROR("Cannot view ICanBufferFactory interface in device: %s.\n", canBus.c_str()); return false; } - iCanBusSharers.resize(ids.size()); + iCanBusSharers.resize(nodes->size()); + + int canRxBufferSize = config.check("canBusRxBufferSize", yarp::os::Value(DEFAULT_CAN_RX_BUFFER_SIZE), "CAN bus RX buffer size").asInt(); + int canTxBufferSize = config.check("canBusTxBufferSize", yarp::os::Value(DEFAULT_CAN_TX_BUFFER_SIZE), "CAN bus TX buffer size").asInt(); + double canRxPeriodMs = config.check("canRxPeriodMs", yarp::os::Value(DEFAULT_CAN_RX_PERIOD_MS), "CAN bus RX period (milliseconds)").asFloat64(); + double canTxPeriodMs = config.check("canTxPeriodMs", yarp::os::Value(DEFAULT_CAN_TX_PERIOD_MS), "CAN bus TX period (milliseconds)").asFloat64(); + + canReaderThread = new CanReaderThread(canBus, iCanBusSharers); + canReaderThread->setCanHandles(iCanBus, iCanBufferFactory, canRxBufferSize); + canReaderThread->setPeriod(canRxPeriodMs); + + canWriterThread = new CanWriterThread(canBus); + canWriterThread->setCanHandles(iCanBus, iCanBufferFactory, canTxBufferSize); + canWriterThread->setPeriod(canTxPeriodMs); + + linInterpPeriodMs = config.check("linInterpPeriodMs", yarp::os::Value(DEFAULT_LIN_INTERP_PERIOD_MS), "linear interpolation mode period (milliseconds)").asInt32(); + linInterpBufferSize = config.check("linInterpBufferSize", yarp::os::Value(DEFAULT_LIN_INTERP_BUFFER_SIZE), "linear interpolation mode buffer size").asInt32(); + linInterpMode = config.check("linInterpMode", yarp::os::Value(DEFAULT_LIN_INTERP_MODE), "linear interpolation mode (pt/pvt)").asString(); + + int parallelCanThreadLimit = config.check("parallelCanThreadLimit", yarp::os::Value(0), "parallel CAN TX thread limit").asInt32(); + + if (parallelCanThreadLimit > 0) + { + deviceMapper.enableParallelization(parallelCanThreadLimit); + } - for (int i = 0; i < ids.size(); i++) + for (int i = 0; i < nodes->size(); i++) { - if (types.get(i).asString().empty()) + std::string node = nodes->get(i).asString(); + yarp::os::Bottle & nodeGroup = config.findGroup(node); + + if (nodeGroup.isNull()) { - CD_WARNING("Argument \"types\" empty at %d.\n", i); + CD_ERROR("Missing CAN node device group %s.\n", node.c_str()); + return false; } - yarp::os::Property options; - options.put("device", types.get(i)); - options.put("canId", ids.get(i)); - options.put("tr", trs.get(i)); - options.put("min", mins.get(i)); - options.put("max", maxs.get(i)); - options.put("maxVel", maxVels.get(i)); - options.put("k", ks.get(i)); - options.put("refAcceleration", refAccelerations.get(i)); - options.put("refSpeed", refSpeeds.get(i)); - options.put("encoderPulses", encoderPulsess.get(i)); - options.put("pulsesPerSample", pulsesPerSamples.get(i)); - options.put("linInterpPeriodMs", linInterpPeriodMs); - options.put("linInterpBufferSize", linInterpBufferSize); - options.put("linInterpMode", linInterpMode); - options.put("canSdoTimeoutMs", canSdoTimeoutMs); - options.put("canDriveStateTimeout", canDriveStateTimeout); - options.put("cuiTimeout", cuiTimeout); - std::string context = types.get(i).asString() + "_" + std::to_string(ids.get(i).asInt32()); - options.setMonitor(config.getMonitor(),context.c_str()); - - yarp::dev::PolyDriver * device = new yarp::dev::PolyDriver(options); - - if (!device->isValid()) + yarp::os::Property nodeOptions; + nodeOptions.fromString(nodeGroup.toString(), false); + nodeOptions.fromString(config.toString(), false); + nodeOptions.setMonitor(config.getMonitor(), node.c_str()); + + yarp::dev::PolyDriver * device = new yarp::dev::PolyDriver; + nodeDevices.push(device, node.c_str()); + + if (!device->open(nodeOptions)) { - CD_ERROR("CAN node [%d] '%s' instantiation failure.\n", i, types.get(i).asString().c_str()); + CD_ERROR("CAN node device %s configuration failure.\n", node.c_str()); return false; } - nodes.push(device, ""); // TODO: device key - if (!deviceMapper.registerDevice(device)) { CD_ERROR("Unable to register device.\n"); @@ -127,24 +129,24 @@ bool CanBusControlboard::open(yarp::os::Searchable & config) iCanBusSharers[i]->registerSender(canWriterThread->getDelegate()); - if (!iCanBus->canIdAdd(ids.get(i).asInt32())) + if (!iCanBus->canIdAdd(iCanBusSharers[i]->getId())) { - CD_ERROR("Cannot register acceptance filter for node ID: %d.\n", ids.get(i).asInt32()); + CD_ERROR("Cannot register acceptance filter for node ID: %d.\n", iCanBusSharers[i]->getId()); return false; } } - const std::string canDevice = canBusOptions.find("canDevice").asString(); - - canReaderThread = new CanReaderThread(canDevice, iCanBusSharers); - canReaderThread->setCanHandles(iCanBus, iCanBufferFactory, canRxBufferSize); - canReaderThread->setPeriod(canRxPeriodMs); - canReaderThread->start(); + if (!canReaderThread->start()) + { + CD_ERROR("Unable to start reader thread.\n"); + return false; + } - canWriterThread = new CanWriterThread(canDevice); - canWriterThread->setCanHandles(iCanBus, iCanBufferFactory, canTxBufferSize); - canWriterThread->setPeriod(canTxPeriodMs); - canWriterThread->start(); + if (!canWriterThread->start()) + { + CD_ERROR("Unable to start writer thread.\n"); + return false; + } for (auto p : iCanBusSharers) { @@ -178,10 +180,10 @@ bool CanBusControlboard::close() ok &= p->finalize(); } - for (int i = 0; i < nodes.size(); i++) + for (int i = 0; i < nodeDevices.size(); i++) { - ok &= nodes[i]->poly->close(); - delete nodes[i]->poly; + ok &= nodeDevices[i]->poly->close(); + delete nodeDevices[i]->poly; } if (canWriterThread && canWriterThread->isRunning()) diff --git a/libraries/YarpPlugins/CanBusControlboard/IControlModeImpl.cpp b/libraries/YarpPlugins/CanBusControlboard/IControlModeImpl.cpp index 982c4d75a..b3ed03ac4 100644 --- a/libraries/YarpPlugins/CanBusControlboard/IControlModeImpl.cpp +++ b/libraries/YarpPlugins/CanBusControlboard/IControlModeImpl.cpp @@ -60,7 +60,7 @@ bool CanBusControlboard::setControlModes(int * modes) return false; } - for (unsigned int i = 0; i < nodes.size(); i++) + for (unsigned int i = 0; i < nodeDevices.size(); i++) { posdThread->updateControlModeRegister(i, modes[i] == VOCAB_CM_POSITION_DIRECT); } diff --git a/libraries/YarpPlugins/CanBusHico/CanBusHico.hpp b/libraries/YarpPlugins/CanBusHico/CanBusHico.hpp index dc2db2438..0e5f5724d 100644 --- a/libraries/YarpPlugins/CanBusHico/CanBusHico.hpp +++ b/libraries/YarpPlugins/CanBusHico/CanBusHico.hpp @@ -17,18 +17,18 @@ #include "hico_api.h" #include "HicoCanMessage.hpp" -#define DEFAULT_CAN_DEVICE "/dev/can0" -#define DEFAULT_CAN_BITRATE 1000000 +#define DEFAULT_PORT "/dev/can0" +#define DEFAULT_BITRATE 1000000 -#define DEFAULT_CAN_RX_TIMEOUT_MS 1 -#define DEFAULT_CAN_TX_TIMEOUT_MS 0 // '0' means no timeout +#define DEFAULT_RX_TIMEOUT_MS 1 +#define DEFAULT_TX_TIMEOUT_MS 0 // '0' means no timeout -#define DEFAULT_CAN_BLOCKING_MODE true -#define DEFAULT_CAN_ALLOW_PERMISSIVE false +#define DEFAULT_BLOCKING_MODE true +#define DEFAULT_ALLOW_PERMISSIVE false #define DELAY 0.001 // [s] -#define DEFAULT_CAN_FILTER_CONFIGURATION "disabled" +#define DEFAULT_FILTER_CONFIGURATION "disabled" namespace roboticslab { @@ -51,10 +51,10 @@ class CanBusHico : public yarp::dev::DeviceDriver, public: CanBusHico() : fileDescriptor(0), - rxTimeoutMs(DEFAULT_CAN_RX_TIMEOUT_MS), - txTimeoutMs(DEFAULT_CAN_TX_TIMEOUT_MS), - blockingMode(DEFAULT_CAN_BLOCKING_MODE), - allowPermissive(DEFAULT_CAN_ALLOW_PERMISSIVE), + rxTimeoutMs(DEFAULT_RX_TIMEOUT_MS), + txTimeoutMs(DEFAULT_TX_TIMEOUT_MS), + blockingMode(DEFAULT_BLOCKING_MODE), + allowPermissive(DEFAULT_ALLOW_PERMISSIVE), filterManager(NULL), filterConfig(FilterManager::DISABLED) {} diff --git a/libraries/YarpPlugins/CanBusHico/DeviceDriverImpl.cpp b/libraries/YarpPlugins/CanBusHico/DeviceDriverImpl.cpp index a04fb3bb6..abe07159e 100644 --- a/libraries/YarpPlugins/CanBusHico/DeviceDriverImpl.cpp +++ b/libraries/YarpPlugins/CanBusHico/DeviceDriverImpl.cpp @@ -19,18 +19,18 @@ bool roboticslab::CanBusHico::open(yarp::os::Searchable& config) { - std::string devicePath = config.check("canDevice", yarp::os::Value(DEFAULT_CAN_DEVICE), "CAN device path").asString(); - int bitrate = config.check("canBitrate", yarp::os::Value(DEFAULT_CAN_BITRATE), "CAN bitrate (bps)").asInt32(); + std::string devicePath = config.check("port", yarp::os::Value(DEFAULT_PORT), "CAN device path").asString(); + int bitrate = config.check("bitrate", yarp::os::Value(DEFAULT_BITRATE), "CAN bitrate (bps)").asInt32(); - blockingMode = config.check("canBlockingMode", yarp::os::Value(DEFAULT_CAN_BLOCKING_MODE), "CAN blocking mode enabled").asBool(); - allowPermissive = config.check("canAllowPermissive", yarp::os::Value(DEFAULT_CAN_ALLOW_PERMISSIVE), "CAN read/write permissive mode").asBool(); + blockingMode = config.check("blockingMode", yarp::os::Value(DEFAULT_BLOCKING_MODE), "CAN blocking mode enabled").asBool(); + allowPermissive = config.check("allowPermissive", yarp::os::Value(DEFAULT_ALLOW_PERMISSIVE), "CAN read/write permissive mode").asBool(); if (blockingMode) { CD_INFO("Blocking mode enabled for CAN device: %s.\n", devicePath.c_str()); - rxTimeoutMs = config.check("canRxTimeoutMs", yarp::os::Value(DEFAULT_CAN_RX_TIMEOUT_MS), "CAN RX timeout (milliseconds)").asInt32(); - txTimeoutMs = config.check("canTxTimeoutMs", yarp::os::Value(DEFAULT_CAN_TX_TIMEOUT_MS), "CAN TX timeout (milliseconds)").asInt32(); + rxTimeoutMs = config.check("rxTimeoutMs", yarp::os::Value(DEFAULT_RX_TIMEOUT_MS), "CAN RX timeout (milliseconds)").asInt32(); + txTimeoutMs = config.check("txTimeoutMs", yarp::os::Value(DEFAULT_TX_TIMEOUT_MS), "CAN TX timeout (milliseconds)").asInt32(); if (rxTimeoutMs <= 0) { @@ -49,7 +49,7 @@ bool roboticslab::CanBusHico::open(yarp::os::Searchable& config) CD_INFO("Permissive mode flag for read/write operations on CAN device %s: %d.\n", devicePath.c_str(), allowPermissive); - std::string filterConfigStr = config.check("canFilterConfiguration", yarp::os::Value(DEFAULT_CAN_FILTER_CONFIGURATION), + std::string filterConfigStr = config.check("filterConfiguration", yarp::os::Value(DEFAULT_FILTER_CONFIGURATION), "CAN filter configuration (disabled|noRange|maskAndRange)").asString(); CD_INFO("CAN filter configuration for CAN device %s: %s.\n", devicePath.c_str(), filterConfigStr.c_str()); diff --git a/libraries/YarpPlugins/CanBusPeak/CanBusPeak.hpp b/libraries/YarpPlugins/CanBusPeak/CanBusPeak.hpp index 3b5dc391c..2dfb74de7 100644 --- a/libraries/YarpPlugins/CanBusPeak/CanBusPeak.hpp +++ b/libraries/YarpPlugins/CanBusPeak/CanBusPeak.hpp @@ -15,14 +15,14 @@ #include "PeakCanMessage.hpp" -#define DEFAULT_CAN_DEVICE "/dev/pcan0" -#define DEFAULT_CAN_BITRATE 1000000 +#define DEFAULT_PORT "/dev/pcan0" +#define DEFAULT_BITRATE 1000000 -#define DEFAULT_CAN_RX_TIMEOUT_MS 1 -#define DEFAULT_CAN_TX_TIMEOUT_MS 0 // '0' means no timeout +#define DEFAULT_RX_TIMEOUT_MS 1 +#define DEFAULT_TX_TIMEOUT_MS 0 // '0' means no timeout -#define DEFAULT_CAN_BLOCKING_MODE true -#define DEFAULT_CAN_ALLOW_PERMISSIVE false +#define DEFAULT_BLOCKING_MODE true +#define DEFAULT_ALLOW_PERMISSIVE false namespace roboticslab { @@ -76,10 +76,10 @@ class CanBusPeak : public yarp::dev::DeviceDriver, public: CanBusPeak() : fileDescriptor(0), - rxTimeoutMs(DEFAULT_CAN_RX_TIMEOUT_MS), - txTimeoutMs(DEFAULT_CAN_TX_TIMEOUT_MS), - blockingMode(DEFAULT_CAN_BLOCKING_MODE), - allowPermissive(DEFAULT_CAN_ALLOW_PERMISSIVE) + rxTimeoutMs(DEFAULT_RX_TIMEOUT_MS), + txTimeoutMs(DEFAULT_TX_TIMEOUT_MS), + blockingMode(DEFAULT_BLOCKING_MODE), + allowPermissive(DEFAULT_ALLOW_PERMISSIVE) {} // --------- DeviceDriver declarations. Implementation in DeviceDriverImpl.cpp --------- diff --git a/libraries/YarpPlugins/CanBusPeak/DeviceDriverImpl.cpp b/libraries/YarpPlugins/CanBusPeak/DeviceDriverImpl.cpp index fad3c79a4..c97d6b35b 100644 --- a/libraries/YarpPlugins/CanBusPeak/DeviceDriverImpl.cpp +++ b/libraries/YarpPlugins/CanBusPeak/DeviceDriverImpl.cpp @@ -12,12 +12,12 @@ bool roboticslab::CanBusPeak::open(yarp::os::Searchable& config) { - std::string devicePath = config.check("canDevice", yarp::os::Value(DEFAULT_CAN_DEVICE), "CAN device path").asString(); + std::string devicePath = config.check("port", yarp::os::Value(DEFAULT_PORT), "CAN device path").asString(); - int bitrate = config.check("canBitrate", yarp::os::Value(DEFAULT_CAN_BITRATE), "CAN bitrate (bps)").asInt32(); + int bitrate = config.check("bitrate", yarp::os::Value(DEFAULT_BITRATE), "CAN bitrate (bps)").asInt32(); - blockingMode = config.check("canBlockingMode", yarp::os::Value(DEFAULT_CAN_BLOCKING_MODE), "CAN blocking mode enabled").asBool(); - allowPermissive = config.check("canAllowPermissive", yarp::os::Value(DEFAULT_CAN_ALLOW_PERMISSIVE), "CAN read/write permissive mode").asBool(); + blockingMode = config.check("blockingMode", yarp::os::Value(DEFAULT_BLOCKING_MODE), "blocking mode enabled").asBool(); + allowPermissive = config.check("allowPermissive", yarp::os::Value(DEFAULT_ALLOW_PERMISSIVE), "read/write permissive mode").asBool(); int flags = OFD_BITRATE | PCANFD_INIT_STD_MSG_ONLY; @@ -25,8 +25,8 @@ bool roboticslab::CanBusPeak::open(yarp::os::Searchable& config) { CD_INFO("Blocking mode enabled for CAN device: %s.\n", devicePath.c_str()); - rxTimeoutMs = config.check("canRxTimeoutMs", yarp::os::Value(DEFAULT_CAN_RX_TIMEOUT_MS), "RX timeout (milliseconds)").asInt32(); - txTimeoutMs = config.check("canTxTimeoutMs", yarp::os::Value(DEFAULT_CAN_TX_TIMEOUT_MS), "TX timeout (milliseconds)").asInt32(); + rxTimeoutMs = config.check("rxTimeoutMs", yarp::os::Value(DEFAULT_RX_TIMEOUT_MS), "RX timeout (milliseconds)").asInt32(); + txTimeoutMs = config.check("txTimeoutMs", yarp::os::Value(DEFAULT_TX_TIMEOUT_MS), "TX timeout (milliseconds)").asInt32(); if (rxTimeoutMs <= 0) { diff --git a/libraries/YarpPlugins/JointCalibrator/DeviceDriverImpl.cpp b/libraries/YarpPlugins/JointCalibrator/DeviceDriverImpl.cpp index 71bb9bfee..652ee14bc 100644 --- a/libraries/YarpPlugins/JointCalibrator/DeviceDriverImpl.cpp +++ b/libraries/YarpPlugins/JointCalibrator/DeviceDriverImpl.cpp @@ -2,11 +2,56 @@ #include "JointCalibrator.hpp" +#include + using namespace roboticslab; +namespace +{ + bool checkAndSet(int axes, const yarp::os::Searchable & config, std::vector & v, + const std::string & key, const std::string & keys, const std::string & comment) + { + if (config.check(key, "(shared) " + comment)) + { + v.assign(axes, config.find(key).asFloat64()); + } + else if (config.check(keys, comment)) + { + yarp::os::Bottle * parsed = config.find(keys).asList(); + + for (auto i = 0; i < parsed->size(); i++) + { + v.push_back(parsed->get(i).asFloat64()); + } + } + else + { + CD_ERROR("Missing %s/%s key or size mismatch.\n", key.c_str(), keys.c_str()); + return false; + } + + return true; + } +} + bool JointCalibrator::open(yarp::os::Searchable & config) { - return true; + CD_DEBUG("$s\n", config.toString().c_str()); + + axes = config.check("joints", yarp::os::Value(0), "number of controlled axes").asInt32(); + + if (axes == 0) + { + CD_ERROR("Illegal axis count: %d.\n", axes); + return false; + } + + return checkAndSet(axes, config, homeSpecs.pos, "home", "homes", "zero position (degrees)") + && checkAndSet(axes, config, homeSpecs.vel, "homeVel", "homeVels", "zero velocity (degrees/second)") + && checkAndSet(axes, config, homeSpecs.acc, "homeAcc", "homeAccs", "zero acceleration (degrees/second^2)") + && checkAndSet(axes, config, parkSpecs.pos, "park", "parks", "zero position (degrees)") + && checkAndSet(axes, config, parkSpecs.vel, "parkVel", "parkVels", "zero velocity (degrees/second)") + && checkAndSet(axes, config, parkSpecs.acc, "parkAcc", "parkAccs", "zero acceleration (degrees/second^2)"); } bool JointCalibrator::close() diff --git a/libraries/YarpPlugins/JointCalibrator/IRemoteCalibratorImpl.cpp b/libraries/YarpPlugins/JointCalibrator/IRemoteCalibratorImpl.cpp index a456da871..8598ca2df 100644 --- a/libraries/YarpPlugins/JointCalibrator/IRemoteCalibratorImpl.cpp +++ b/libraries/YarpPlugins/JointCalibrator/IRemoteCalibratorImpl.cpp @@ -2,178 +2,188 @@ #include "JointCalibrator.hpp" -#include +#include + +#include #include using namespace roboticslab; -bool JointCalibrator::calibrateSingleJoint(int j) +namespace { - CD_WARNING("Not supported.\n"); - return false; + constexpr double MOTION_CHECK_INTERVAL = 0.1; // seconds + constexpr double POSITION_EPSILON = 1e-3; // degrees } -bool JointCalibrator::calibrateWholePart() +bool JointCalibrator::move(const std::vector & joints, const MovementSpecs & specs) { - CD_WARNING("Not supported.\n"); - return false; -} + for (int joint : joints) + { + if (joint < 0 || joint > axes - 1) + { + CD_ERROR("Invalid joint id: %d.\n", joint); + return false; + } + } -bool JointCalibrator::homingSingleJoint(int j) -{ - if (j < 0 || j > axes - 1) + std::vector encs; + + if (!iEncoders->getEncoders(encs.data())) { - CD_ERROR("Invalid joint id: %d.\n", j); + CD_ERROR("Unable to retrieve initial position.\n"); return false; } - CD_INFO("Starting homing procedure on joint %d.\n", j); + std::vector ids; + + for (int joint : joints) + { + if (std::abs(encs[joint] - specs.pos[joint]) < POSITION_EPSILON) + { + CD_INFO("Joint %d already in target position.\n", joint); + continue; + } - yarp::conf::vocab32_t initialMode; + ids.push_back(joint); + } - if (!iControlMode->getControlMode(j, &initialMode)) + if (ids.empty()) { - CD_ERROR("Unable to retrieve initial control mode.\n"); - return false; + CD_INFO("All joints in target position, not moving.\n"); + return true; } - if (initialMode != VOCAB_CM_POSITION && !iControlMode->setControlMode(j, VOCAB_CM_POSITION)) + std::vector initialRefSpeeds(ids.size()); + + if (!iPositionControl->getRefSpeeds(ids.size(), ids.data(), initialRefSpeeds.data())) { - CD_ERROR("Unable to switch to position mode.\n"); + CD_ERROR("Unable to retrieve initial reference speeds.\n"); return false; } - double enc; + std::vector initialRefAccs(ids.size()); - if (!iEncoders->getEncoder(j, &enc)) + if (!iPositionControl->getRefAccelerations(ids.size(), ids.data(), initialRefAccs.data())) { - CD_ERROR("Unable to retrieve current position.\n"); + CD_ERROR("Unable to retrieve initial reference accelerations.\n"); return false; } - CD_INFO("Current position: %f.\n", enc); + std::vector targetModes(ids.size(), VOCAB_CM_POSITION); - if (!iPositionControl->positionMove(j, 0.0)) + if (!iControlMode->setControlModes(ids.size(), ids.data(), targetModes.data())) { - CD_ERROR("Unable to move motors to zero.\n"); + CD_ERROR("Unable to switch to position mode.\n"); return false; } - bool done; + std::vector targetRefSpeeds; + std::vector targetRefAccs; + std::vector targets; - while (!iPositionControl->checkMotionDone(j, &done)) + for (int id : ids) { - yarp::os::Time::delay(0.1); + targetRefSpeeds.push_back(specs.vel[id]); + targetRefAccs.push_back(specs.acc[id]); + targets.push_back(specs.pos[id]); } - if (initialMode != VOCAB_CM_POSITION && !iControlMode->setControlMode(j, initialMode)) + if (!iPositionControl->setRefSpeeds(ids.size(), ids.data(), targetRefSpeeds.data())) { - CD_ERROR("Unable to restore original control mode.\n"); + CD_ERROR("Unable to set new reference speeds.\n"); return false; } - CD_INFO("Homing procedure on joint %d finished.\n", j); - - return true; -} - -bool JointCalibrator::homingWholePart() -{ - CD_INFO("Starting homing procedure.\n"); - - std::vector initialModes(axes); - - if (!iControlMode->getControlModes(initialModes.data())) + if (!iPositionControl->setRefAccelerations(ids.size(), ids.data(), targetRefAccs.data())) { - CD_ERROR("Unable to retrieve initial control modes.\n"); + CD_ERROR("Unable to set new reference accelerations.\n"); return false; } - std::vector jointIds; - - for (std::size_t i = 0; i < initialModes.size(); i++) + if (!iPositionControl->positionMove(ids.size(), ids.data(), targets.data())) { - if (initialModes[i] != VOCAB_CM_POSITION) - { - jointIds.push_back(i); - } + CD_ERROR("Unable to move motors to new position.\n"); + return false; } - if (!jointIds.empty()) - { - std::vector modes(jointIds.size(), VOCAB_CM_POSITION); + bool done; - if (!iControlMode->setControlModes(jointIds.size(), jointIds.data(), modes.data())) - { - CD_ERROR("Unable to switch to position mode.\n"); - return false; - } + while (!iPositionControl->checkMotionDone(ids.size(), ids.data(), &done)) + { + yarp::os::Time::delay(MOTION_CHECK_INTERVAL); } - std::vector encs(axes); - if (!iEncoders->getEncoders(encs.data())) { - CD_ERROR("Unable to retrieve current position.\n"); + CD_ERROR("Unable to retrieve target position.\n"); return false; } - CD_INFO("Current position:"); - - for (auto enc : encs) + for (int id : ids) { - CD_INFO_NO_HEADER(" %f", enc); + if (std::abs(encs[id] - specs.pos[id]) > POSITION_EPSILON) + { + CD_ERROR("Joint %d has not reached the desired position.\n", id); + return false; + } } - CD_INFO_NO_HEADER("\n"); - - std::vector poss(axes, 0.0); - - if (!iPositionControl->positionMove(poss.data())) + if (!iPositionControl->setRefSpeeds(ids.size(), ids.data(), initialRefSpeeds.data())) { - CD_ERROR("Unable to move motors to zero.\n"); + CD_ERROR("Unable to restore initial reference speeds.\n"); return false; } - bool done; - - while (!iPositionControl->checkMotionDone(&done)) + if (!iPositionControl->setRefAccelerations(ids.size(), ids.data(), initialRefAccs.data())) { - yarp::os::Time::delay(0.1); + CD_ERROR("Unable to restore initial reference accelerations.\n"); + return false; } - if (!jointIds.empty()) - { - std::vector modes; + return true; +} - for (auto jointId : jointIds) - { - modes.push_back(initialModes[jointId]); - } +bool JointCalibrator::calibrateSingleJoint(int j) +{ + CD_WARNING("Not supported.\n"); + return false; +} - if (!iControlMode->setControlModes(jointIds.size(), jointIds.data(), modes.data())) - { - CD_ERROR("Unable to restore original control modes.\n"); - return false; - } - } +bool JointCalibrator::calibrateWholePart() +{ + CD_WARNING("Not supported.\n"); + return false; +} - CD_INFO("Homing procedure finished.\n"); +bool JointCalibrator::homingSingleJoint(int j) +{ + CD_INFO("Performing homing procedure on joint %d.\n", j); + std::vector targets{j}; + return move(targets, homeSpecs); +} - return true; +bool JointCalibrator::homingWholePart() +{ + CD_INFO("Performing homing procedure on whole part.\n"); + std::vector targets(axes); + std::iota(targets.begin(), targets.end(), 0); + return move(targets, homeSpecs); } bool JointCalibrator::parkSingleJoint(int j, bool wait) { - CD_WARNING("Not supported.\n"); - return false; + CD_INFO("Performing park procedure on joint %d.\n", j); + std::vector targets{j}; + return move(targets, parkSpecs); } bool JointCalibrator::parkWholePart() { - CD_WARNING("Not supported.\n"); - return false; + CD_INFO("Performing park procedure on whole part.\n"); + std::vector targets(axes); + std::iota(targets.begin(), targets.end(), 0); + return move(targets, parkSpecs); } bool JointCalibrator::quitCalibrate() diff --git a/libraries/YarpPlugins/JointCalibrator/IWrapperImpl.cpp b/libraries/YarpPlugins/JointCalibrator/IWrapperImpl.cpp index 918533de3..dd76f77ad 100644 --- a/libraries/YarpPlugins/JointCalibrator/IWrapperImpl.cpp +++ b/libraries/YarpPlugins/JointCalibrator/IWrapperImpl.cpp @@ -6,10 +6,13 @@ using namespace roboticslab; bool JointCalibrator::attach(yarp::dev::PolyDriver * poly) { + int localAxes; + return poly->view(iControlMode) && poly->view(iEncoders) && poly->view(iPositionControl) - && iEncoders->getAxes(&axes); + && iEncoders->getAxes(&localAxes) + && localAxes == axes; } bool JointCalibrator::detach() diff --git a/libraries/YarpPlugins/JointCalibrator/JointCalibrator.hpp b/libraries/YarpPlugins/JointCalibrator/JointCalibrator.hpp index 2327264db..30152bd57 100644 --- a/libraries/YarpPlugins/JointCalibrator/JointCalibrator.hpp +++ b/libraries/YarpPlugins/JointCalibrator/JointCalibrator.hpp @@ -3,6 +3,8 @@ #ifndef __JOINT_CALIBRATOR_HPP__ #define __JOINT_CALIBRATOR_HPP__ +#include + #include #include #include @@ -19,6 +21,17 @@ namespace roboticslab * @brief Contains roboticslab::JointCalibrator. */ +/** + * @ingroup JointCalibrator + * @brief ... + */ +struct MovementSpecs +{ + std::vector pos; + std::vector vel; + std::vector acc; +}; + /** * @ingroup JointCalibrator * @brief ... @@ -48,7 +61,13 @@ class JointCalibrator : public yarp::dev::DeviceDriver, virtual bool close(); private: + bool move(const std::vector & joints, const MovementSpecs & specs); + int axes; + + MovementSpecs homeSpecs; + MovementSpecs parkSpecs; + yarp::dev::IControlMode * iControlMode; yarp::dev::IEncoders * iEncoders; yarp::dev::IPositionControl * iPositionControl; diff --git a/libraries/YarpPlugins/TechnosoftIpos/DeviceDriverImpl.cpp b/libraries/YarpPlugins/TechnosoftIpos/DeviceDriverImpl.cpp index 5956d9549..17d28e602 100644 --- a/libraries/YarpPlugins/TechnosoftIpos/DeviceDriverImpl.cpp +++ b/libraries/YarpPlugins/TechnosoftIpos/DeviceDriverImpl.cpp @@ -4,6 +4,8 @@ #include +#include + #include using namespace roboticslab; @@ -14,21 +16,27 @@ bool TechnosoftIpos::open(yarp::os::Searchable & config) { CD_DEBUG("%s\n", config.toString().c_str()); - int canId = config.check("canId", yarp::os::Value(0), "CAN bus ID").asInt32(); + int canId = config.check("canId", yarp::os::Value(0), "CAN node ID").asInt32(); + + yarp::os::Bottle & driverGroup = config.findGroup("driver"); + yarp::os::Bottle & motorGroup = config.findGroup("motor"); + yarp::os::Bottle & gearboxGroup = config.findGroup("gearbox"); + yarp::os::Bottle & encoderGroup = config.findGroup("encoder"); // mutable variables - vars.tr = config.check("tr", yarp::os::Value(0.0), "reduction").asFloat64(); - vars.k = config.check("k", yarp::os::Value(0.0), "motor constant").asFloat64(); - vars.encoderPulses = config.check("encoderPulses", yarp::os::Value(0), "encoderPulses").asInt32(); - vars.pulsesPerSample = config.check("pulsesPerSample", yarp::os::Value(0), "pulsesPerSample").asInt32(); + vars.tr = gearboxGroup.check("tr", yarp::os::Value(0.0), "reduction").asFloat64(); + vars.k = motorGroup.check("k", yarp::os::Value(0.0), "motor constant").asFloat64(); + vars.encoderPulses = encoderGroup.check("encoderPulses", yarp::os::Value(0), "encoderPulses").asInt32(); + vars.pulsesPerSample = motorGroup.check("pulsesPerSample", yarp::os::Value(0), "pulsesPerSample").asInt32(); + vars.tr = vars.tr * config.check("extraTr", yarp::os::Value(1.0), "extra reduction").asFloat64(); vars.actualControlMode = VOCAB_CM_NOT_CONFIGURED; // immutable variables - vars.drivePeakCurrent = config.check("drivePeakCurrent", yarp::os::Value(0.0), "peak drive current (amperes)").asFloat64(); + vars.drivePeakCurrent = driverGroup.check("peakCurrent", yarp::os::Value(0.0), "peak drive current (amperes)").asFloat64(); vars.maxVel = config.check("maxVel", yarp::os::Value(0.0), "maxVel (meters/second or degrees/second)").asFloat64(); - vars.axisName = config.check("axisName", yarp::os::Value(""), "axis name").asString(); - vars.jointType = config.check("jointType", yarp::os::Value(yarp::dev::VOCAB_JOINTTYPE_UNKNOWN), "joint type [atrv|atpr|unkn]").asVocab(); + vars.axisName = config.check("name", yarp::os::Value(""), "axis name").asString(); + vars.jointType = config.check("type", yarp::os::Value(yarp::dev::VOCAB_JOINTTYPE_UNKNOWN), "joint type [atrv|atpr|unkn]").asVocab(); vars.reverse = config.check("reverse", yarp::os::Value(false), "reverse motor encoder counts").asBool(); vars.min = config.check("min", yarp::os::Value(0.0), "min (meters or degrees)").asFloat64(); vars.max = config.check("max", yarp::os::Value(0.0), "max (meters or degrees)").asFloat64(); @@ -41,11 +49,23 @@ bool TechnosoftIpos::open(yarp::os::Searchable & config) return false; } - if (config.check("externalEncoder", "external encoder device")) + if (config.check("externalEncoder", "external encoder")) { std::string externalEncoder = config.find("externalEncoder").asString(); + yarp::os::Bottle & externalEncoderGroup = config.findGroup(externalEncoder); + + if (externalEncoderGroup.isNull()) + { + CD_ERROR("Missing external encoder device group %s.\n", externalEncoder.c_str()); + return false; + } + + yarp::os::Property externalEncoderOptions; + externalEncoderOptions.fromString(externalEncoderGroup.toString(), false); + externalEncoderOptions.fromString(config.toString(), false); + externalEncoderOptions.setMonitor(config.getMonitor(), externalEncoder.c_str()); - if (!externalEncoderDevice.open(externalEncoder)) + if (!externalEncoderDevice.open(externalEncoderOptions)) { CD_ERROR("Unable to open external encoder device: %s.\n", externalEncoder.c_str()); return false; diff --git a/programs/launchCanBus/LaunchCanBus.cpp b/programs/launchCanBus/LaunchCanBus.cpp index 9d1835bea..00b469ba4 100644 --- a/programs/launchCanBus/LaunchCanBus.cpp +++ b/programs/launchCanBus/LaunchCanBus.cpp @@ -33,112 +33,87 @@ bool LaunchCanBus::configure(yarp::os::ResourceFinder &rf) return false; } - yarp::conf::vocab32_t mode = rf.check("mode", yarp::os::Value(VOCAB_CM_POSITION), "initial mode of operation").asVocab(); - bool homing = rf.check("home", yarp::os::Value(false), "perform initial homing procedure").asBool(); - - const std::string canDevicePrefix = "devCan"; - int canDeviceId = 0; + yarp::os::Property robotConfig; + std::string configPath = rf.findFileByName("config.ini"); - while (true) + if (configPath.empty() || !robotConfig.fromConfigFile(configPath)) { - std::string canDeviceLabel = canDevicePrefix + std::to_string(canDeviceId); - - yarp::os::Bottle canDeviceGroup = rf.findGroup(canDeviceLabel); - - if (canDeviceGroup.isNull()) - { - break; - } - - CD_DEBUG("%s\n", canDeviceGroup.toString().c_str()); - - yarp::os::Property canDeviceOptions; - canDeviceOptions.fromString(canDeviceGroup.toString()); - canDeviceOptions.put("home", homing); + CD_ERROR("File %s does not exist or unsufficient permissions.\n", configPath.c_str()); + return false; + } - yarp::dev::PolyDriver * canDevice = new yarp::dev::PolyDriver(canDeviceOptions); + yarp::conf::vocab32_t mode = rf.check("mode", yarp::os::Value(VOCAB_CM_POSITION), "initial mode of operation").asVocab(); + bool homing = rf.check("home", yarp::os::Value(false), "perform initial homing procedure").asBool(); - if (!canDevice->isValid()) - { - CD_ERROR("CAN device %s instantiation failure.\n", canDeviceLabel.c_str()); - return false; - } + yarp::os::Bottle devCan = rf.findGroup("devCan", "CAN controlboard devices").tail(); + yarp::os::Bottle wrapper = rf.findGroup("wrapper", "YARP wrappers devices").tail(); - canDevices.push(canDevice, canDeviceLabel.c_str()); - canDeviceId++; + if (devCan.isNull() || devCan.size() == 0) + { + CD_ERROR("Missing or empty \"devCan\" section collection.\n"); + return false; } - if (canDeviceId == 0) + if (wrapper.isNull() || wrapper.size() == 0) { - CD_ERROR("Empty CAN device list.\n"); + CD_ERROR("Missing or empty \"wrapper\" section collection.\n"); return false; } - const std::string calibratorDevicePrefix = "calibrator"; - int calibratorDeviceId = 0; + // CAN devices - while (true) + for (int i = 0; i < devCan.size(); i++) { - std::string calibratorDeviceLabel = calibratorDevicePrefix + std::to_string(calibratorDeviceId); - yarp::os::Bottle calibratorDeviceGroup = rf.findGroup(calibratorDeviceLabel); - - if (calibratorDeviceGroup.isNull()) - { - break; - } + std::string canDeviceLabel = devCan.get(i).asString(); + const yarp::os::Bottle & canDeviceGroup = rf.findGroup(canDeviceLabel); - CD_DEBUG("%s\n", calibratorDeviceGroup.toString().c_str()); - - yarp::os::Property calibratorDeviceOptions; - calibratorDeviceOptions.fromString(calibratorDeviceGroup.toString()); - - yarp::dev::PolyDriver * calibratorDevice = new yarp::dev::PolyDriver(calibratorDeviceOptions); - - if (!calibratorDevice->isValid()) + if (canDeviceGroup.isNull()) { - CD_ERROR("Calibrator device %s instantiation failure.\n", calibratorDeviceLabel.c_str()); + CD_ERROR("Missing CAN device group %s.\n", canDeviceLabel.c_str()); return false; } - yarp::dev::IRemoteCalibrator * iRemoteCalibrator; + yarp::os::Property canDeviceOptions; + canDeviceOptions.fromString(canDeviceGroup.toString(), false); + canDeviceOptions.fromString(robotConfig.toString(), false); + canDeviceOptions.put("home", homing); + + yarp::dev::PolyDriver * canDevice = new yarp::dev::PolyDriver; + canDevices.push(canDevice, canDeviceLabel.c_str()); - if (!calibratorDevice->view(iRemoteCalibrator)) + if (!canDevice->open(canDeviceOptions)) { - CD_ERROR("Unable to view IRemoteCalibrator in %s.\n", calibratorDeviceLabel.c_str()); + CD_ERROR("CAN device %s configuration failure.\n", canDeviceLabel.c_str()); return false; } - - calibratorDevices.push(calibratorDevice, "calibrator"); // key value enforced by CBW2.attachAll() } - const std::string wrapperDevicePrefix = "wrapper"; - int wrapperDeviceId = 0; + // network wrappers - while (true) + for (int i = 0; i < wrapper.size(); i++) { - std::string wrapperDeviceLabel = wrapperDevicePrefix + std::to_string(wrapperDeviceId); - yarp::os::Bottle wrapperDeviceGroup = rf.findGroup(wrapperDeviceLabel); + std::string wrapperDeviceLabel = wrapper.get(i).asString(); + const yarp::os::Bottle & wrapperDeviceGroup = rf.findGroup(wrapperDeviceLabel); if (wrapperDeviceGroup.isNull()) { - break; + CD_ERROR("Missing wrapper device group %s.\n", wrapperDeviceLabel.c_str()); + return false; } - CD_DEBUG("%s\n", wrapperDeviceGroup.toString().c_str()); - yarp::os::Property wrapperDeviceOptions; wrapperDeviceOptions.fromString(wrapperDeviceGroup.toString()); + wrapperDeviceOptions.unput("calibrator"); // custom property added by us - yarp::dev::PolyDriver * wrapperDevice = new yarp::dev::PolyDriver(wrapperDeviceOptions); + yarp::dev::PolyDriver * wrapperDevice = new yarp::dev::PolyDriver; + wrapperDevices.push(wrapperDevice, wrapperDeviceLabel.c_str()); - if (!wrapperDevice->isValid()) + if (!wrapperDevice->open(wrapperDeviceOptions)) { - CD_ERROR("Wrapper device %s instantiation failure.\n", wrapperDeviceLabel.c_str()); + CD_ERROR("Wrapper device %s configuration failure.\n", wrapperDeviceLabel.c_str()); return false; } - wrapperDevices.push(wrapperDevice, wrapperDeviceLabel.c_str()); - yarp::dev::IMultipleWrapper * iMultipleWrapper; if (!wrapperDevice->view(iMultipleWrapper)) @@ -150,14 +125,46 @@ bool LaunchCanBus::configure(yarp::os::ResourceFinder &rf) yarp::dev::PolyDriverList temp; temp = canDevices; - if (calibratorDevices.size() - 1 >= wrapperDeviceId) + std::string calibratorDeviceLabel = wrapperDeviceGroup.find("calibrator").asString(); + + if (!calibratorDeviceLabel.empty()) { - yarp::dev::PolyDriver * calibratorDevice = calibratorDevices[wrapperDeviceId]->poly; + yarp::os::Bottle & calibratorDeviceGroup = robotConfig.findGroup(calibratorDeviceLabel); + + if (calibratorDeviceGroup.isNull()) + { + CD_ERROR("Missing calibrator device group %s.\n", calibratorDeviceLabel.c_str()); + return false; + } + + yarp::os::Property calibratorDeviceOptions; + calibratorDeviceOptions.fromString(calibratorDeviceGroup.toString(), false); + calibratorDeviceOptions.fromString(robotConfig.toString(), false); + calibratorDeviceOptions.put("joints", wrapperDeviceOptions.find("joints")); + + yarp::dev::PolyDriver * calibratorDevice = new yarp::dev::PolyDriver; + yarp::dev::PolyDriverDescriptor descriptor(calibratorDevice, "calibrator"); // key name enforced by CBW2::attachAll() + calibratorDevices.push(descriptor); + + if (!calibratorDevice->open(calibratorDeviceOptions)) + { + CD_ERROR("Calibrator device %s configuration failure.\n", calibratorDeviceLabel.c_str()); + return false; + } + + yarp::dev::IRemoteCalibrator * iRemoteCalibrator; + + if (!calibratorDevice->view(iRemoteCalibrator)) + { + CD_ERROR("Unable to view IRemoteCalibrator in calibrator device %s.\n", calibratorDeviceLabel.c_str()); + return false; + } + yarp::dev::IWrapper * iWrapper; if (!calibratorDevice->view(iWrapper)) { - CD_ERROR("Unable to view IWrapper in calibrator device.\n"); + CD_ERROR("Unable to view IWrapper in calibrator device %s.\n", calibratorDeviceLabel.c_str()); return false; } @@ -167,7 +174,7 @@ bool LaunchCanBus::configure(yarp::os::ResourceFinder &rf) return false; } - temp.push(*calibratorDevices[wrapperDeviceId]); + temp.push(descriptor); } if (!iMultipleWrapper->attachAll(temp)) @@ -175,21 +182,9 @@ bool LaunchCanBus::configure(yarp::os::ResourceFinder &rf) CD_ERROR("Unable to attach wrapper %s to CAN devices.\n", wrapperDeviceLabel.c_str()); return false; } - - wrapperDeviceId++; } - if (wrapperDeviceId == 0) - { - CD_ERROR("Empty wrapper device list.\n"); - return false; - } - - if (calibratorDeviceId != 0 && wrapperDeviceId != calibratorDeviceId) - { - CD_ERROR("Unbalanced number of wrapper devices (%d) and calibrators (%d).\n", wrapperDeviceId, calibratorDeviceId); - return false; - } + // initial control modes for (int i = 0; i < canDevices.size(); i++) { @@ -227,17 +222,14 @@ bool LaunchCanBus::configure(yarp::os::ResourceFinder &rf) CD_SUCCESS("Set %s mode in %s.\n", yarp::os::Vocab::decode(mode).c_str(), canDevices[i]->key.c_str()); } + // homing on start + if (homing) { for (int i = 0; i < calibratorDevices.size(); i++) { yarp::dev::IRemoteCalibrator * iRemoteCalibrator; - - if (!calibratorDevices[i]->poly->view(iRemoteCalibrator)) - { - CD_ERROR("Unable to view IRemoteCalibrator in %s.\n", calibratorDevices[i]->key.c_str()); - return false; - } + calibratorDevices[i]->poly->view(iRemoteCalibrator); if (!iRemoteCalibrator->homingWholePart()) { @@ -268,14 +260,14 @@ double LaunchCanBus::getPeriod() bool LaunchCanBus::close() { - for (int i = 0; i < wrapperDevices.size(); i++) + for (int i = 0; i < calibratorDevices.size(); i++) { - delete wrapperDevices[i]->poly; + delete calibratorDevices[i]->poly; } - for (int i = 0; i < calibratorDevices.size(); i++) + for (int i = 0; i < wrapperDevices.size(); i++) { - delete calibratorDevices[i]->poly; + delete wrapperDevices[i]->poly; } for (int i = 0; i < canDevices.size(); i++) diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index cc2eb7944..49a9795ce 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -1,28 +1,35 @@ -# Copyright: 2017 UC3M +# Copyright: 2019 UC3M # Author: Juan G Victores and Raul de Santos Rico -# CopyPolicy: Released under the terms of the GNU GPL v2.0. +# CopyPolicy: Released under the terms of the GNU GPL v2.0 -yarp_install(FILES ymanager.ini - DESTINATION ${ROBOTICSLAB-YARP-DEVICES_DATA_INSTALL_DIR}) - -### Go through single applications +set(applications) +set(contexts) if(ENABLE_checkCanBus) - add_subdirectory(checkCanBus) + list(APPEND contexts contexts/checkCanBus) endif() if(ENABLE_dumpCanBus) - add_subdirectory(dumpCanBus) + list(APPEND contexts contexts/dumpCanBus) endif() if(ENABLE_launchCanBus) - add_subdirectory(launchCanBus) + list(APPEND contexts contexts/launchCanBus) endif() if(ENABLE_SpaceNavigator) - add_subdirectory(spaceNavigator) + list(APPEND applications applications/yarpmanager/spaceNavigator) endif() if(ENABLE_tests) - add_subdirectory(testCuiAbsolute) + list(APPEND contexts contexts/testCuiAbsolute) endif() + +yarp_install(FILES applications/yarpmanager/ymanager.ini + DESTINATION ${ROBOTICSLAB-YARP-DEVICES_APPLICATIONS_INSTALL_DIR}/yarpmanager) + +yarp_install(DIRECTORY ${applications} + DESTINATION ${ROBOTICSLAB-YARP-DEVICES_APPLICATIONS_INSTALL_DIR}/yarpmanager) + +yarp_install(DIRECTORY ${contexts} + DESTINATION ${ROBOTICSLAB-YARP-DEVICES_CONTEXTS_INSTALL_DIR}) diff --git a/share/spaceNavigator/scripts/spaceNavigator.xml b/share/applications/yarpmanager/spaceNavigator/spaceNavigator.xml similarity index 100% rename from share/spaceNavigator/scripts/spaceNavigator.xml rename to share/applications/yarpmanager/spaceNavigator/spaceNavigator.xml diff --git a/share/ymanager.ini b/share/applications/yarpmanager/ymanager.ini similarity index 100% rename from share/ymanager.ini rename to share/applications/yarpmanager/ymanager.ini diff --git a/share/checkCanBus/CMakeLists.txt b/share/checkCanBus/CMakeLists.txt deleted file mode 100644 index 8b95dffd0..000000000 --- a/share/checkCanBus/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright: 2014 UC3M -# Author: Raúl de Santos Rico -# CopyPolicy: Released under the terms of the GNU GPL v2.0. - -yarp_install(FILES conf/checkCanBus.ini - conf/checkLocomotionCan0.ini - conf/checkLocomotionCan1.ini - conf/checkManipulationCan2.ini - conf/checkManipulationCan3.ini - DESTINATION ${ROBOTICSLAB-YARP-DEVICES_CONTEXTS_INSTALL_DIR}/checkCanBus) diff --git a/share/checkCanBus/conf/checkCanBus.ini b/share/contexts/checkCanBus/checkCanBus.ini similarity index 100% rename from share/checkCanBus/conf/checkCanBus.ini rename to share/contexts/checkCanBus/checkCanBus.ini diff --git a/share/checkCanBus/conf/checkLocomotionCan0.ini b/share/contexts/checkCanBus/checkLocomotionCan0.ini similarity index 100% rename from share/checkCanBus/conf/checkLocomotionCan0.ini rename to share/contexts/checkCanBus/checkLocomotionCan0.ini diff --git a/share/checkCanBus/conf/checkLocomotionCan1.ini b/share/contexts/checkCanBus/checkLocomotionCan1.ini similarity index 100% rename from share/checkCanBus/conf/checkLocomotionCan1.ini rename to share/contexts/checkCanBus/checkLocomotionCan1.ini diff --git a/share/checkCanBus/conf/checkManipulationCan2.ini b/share/contexts/checkCanBus/checkManipulationCan2.ini similarity index 100% rename from share/checkCanBus/conf/checkManipulationCan2.ini rename to share/contexts/checkCanBus/checkManipulationCan2.ini diff --git a/share/checkCanBus/conf/checkManipulationCan3.ini b/share/contexts/checkCanBus/checkManipulationCan3.ini similarity index 100% rename from share/checkCanBus/conf/checkManipulationCan3.ini rename to share/contexts/checkCanBus/checkManipulationCan3.ini diff --git a/share/dumpCanBus/conf/dumpCanBus.ini b/share/contexts/dumpCanBus/dumpCanBus.ini similarity index 100% rename from share/dumpCanBus/conf/dumpCanBus.ini rename to share/contexts/dumpCanBus/dumpCanBus.ini diff --git a/share/launchCanBus/conf/oneCanBusOneWrapper-CuiAbsolute.ini b/share/contexts/launchCanBus/oneCanBusOneWrapper-CuiAbsolute.ini similarity index 100% rename from share/launchCanBus/conf/oneCanBusOneWrapper-CuiAbsolute.ini rename to share/contexts/launchCanBus/oneCanBusOneWrapper-CuiAbsolute.ini diff --git a/share/launchCanBus/conf/oneCanBusOneWrapper-left-arm.ini b/share/contexts/launchCanBus/oneCanBusOneWrapper-left-arm.ini similarity index 100% rename from share/launchCanBus/conf/oneCanBusOneWrapper-left-arm.ini rename to share/contexts/launchCanBus/oneCanBusOneWrapper-left-arm.ini diff --git a/share/launchCanBus/conf/oneCanBusOneWrapper-right-arm.ini b/share/contexts/launchCanBus/oneCanBusOneWrapper-right-arm.ini similarity index 100% rename from share/launchCanBus/conf/oneCanBusOneWrapper-right-arm.ini rename to share/contexts/launchCanBus/oneCanBusOneWrapper-right-arm.ini diff --git a/share/launchCanBus/conf/oneCanBusOneWrapper.ini b/share/contexts/launchCanBus/oneCanBusOneWrapper.ini similarity index 100% rename from share/launchCanBus/conf/oneCanBusOneWrapper.ini rename to share/contexts/launchCanBus/oneCanBusOneWrapper.ini diff --git a/share/launchCanBus/conf/twoCanBusThreeWrappers.ini b/share/contexts/launchCanBus/twoCanBusThreeWrappers.ini similarity index 100% rename from share/launchCanBus/conf/twoCanBusThreeWrappers.ini rename to share/contexts/launchCanBus/twoCanBusThreeWrappers.ini diff --git a/share/testCuiAbsolute/conf/testCuiAbsolute.ini b/share/contexts/testCuiAbsolute/testCuiAbsolute.ini similarity index 100% rename from share/testCuiAbsolute/conf/testCuiAbsolute.ini rename to share/contexts/testCuiAbsolute/testCuiAbsolute.ini diff --git a/share/dumpCanBus/CMakeLists.txt b/share/dumpCanBus/CMakeLists.txt deleted file mode 100644 index 3b341dd91..000000000 --- a/share/dumpCanBus/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright: 2014 UC3M -# Author: Juan G Victores -# CopyPolicy: Released under the terms of the GNU GPL v2.0. - -yarp_install(FILES conf/dumpCanBus.ini - DESTINATION ${ROBOTICSLAB-YARP-DEVICES_CONTEXTS_INSTALL_DIR}/dumpCanBus) diff --git a/share/launchCanBus/CMakeLists.txt b/share/launchCanBus/CMakeLists.txt deleted file mode 100644 index 57f7f747d..000000000 --- a/share/launchCanBus/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright: 2014 UC3M -# Author: Juan G Victores -# CopyPolicy: Released under the terms of the GNU GPL v2.0. - -yarp_install(FILES conf/oneCanBusOneWrapper.ini - conf/oneCanBusOneWrapper-CuiAbsolute.ini - conf/oneCanBusOneWrapper-left-arm.ini - conf/oneCanBusOneWrapper-right-arm.ini - conf/twoCanBusThreeWrappers.ini - DESTINATION ${ROBOTICSLAB-YARP-DEVICES_CONTEXTS_INSTALL_DIR}/launchCanBus) diff --git a/share/spaceNavigator/CMakeLists.txt b/share/spaceNavigator/CMakeLists.txt deleted file mode 100644 index bf4ca30fc..000000000 --- a/share/spaceNavigator/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -yarp_install(FILES scripts/spaceNavigator.xml - DESTINATION ${ROBOTICSLAB-YARP-DEVICES_APPLICATIONS_INSTALL_DIR}) diff --git a/share/testCuiAbsolute/CMakeLists.txt b/share/testCuiAbsolute/CMakeLists.txt deleted file mode 100644 index ffa1c321f..000000000 --- a/share/testCuiAbsolute/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright: 2014 UC3M -# Author: Raúl de Santos Rico -# CopyPolicy: Released under the terms of the GNU GPL v2.0. - -yarp_install(FILES conf/testCuiAbsolute.ini - DESTINATION ${ROBOTICSLAB-YARP-DEVICES_CONTEXTS_INSTALL_DIR}/testCuiAbsolute)