Skip to content

Commit

Permalink
Fix #6578 Devices with Duplicate Names Cause Unexpected Behavior (#…
Browse files Browse the repository at this point in the history
…6579)

* add device constructors that accept a WbDeviceTag rather than a name

* create populate Robot::deviceList by tag rather than name

* update python api

* remove duplicate Brake destructor

* define WbDeviceTag in Robot

* update java api

* add api test

* bug fixes

* fix Java getDevice implementation

* update documentation

* fix warnings in test

* run clang-format

* make test objects constant

Co-authored-by: Olivier Michel <Olivier.Michel@cyberbotics.com>

* update changelog

* minor clarification

* fix capitalization of API

Co-authored-by: Olivier Michel <Olivier.Michel@cyberbotics.com>

* allow checking if const pointers are null

* use non-const Robot

---------

Co-authored-by: Olivier Michel <Olivier.Michel@cyberbotics.com>
  • Loading branch information
CoolSpy3 and omichel authored Jul 10, 2024
1 parent 1c6c9a3 commit a01ffad
Show file tree
Hide file tree
Showing 38 changed files with 375 additions and 182 deletions.
2 changes: 1 addition & 1 deletion docs/reference/changelog-r2024.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ Released on December **th, 2023.
- Fixed error message on Windows when `libssl-3-x64.dll` was added to `PATH` ([#6553](https://github.com/cyberbotics/webots/pull/6553)).
- Fixed length of arrays returned by `getPose()` in Java ([#6556](https://github.com/cyberbotics/webots/pull/6556)).
- Fixed length of arrays returned by `CameraRecognitionObject.getColors()` in Java ([#6564](https://github.com/cyberbotics/webots/pull/6564))

- Fixed handling of device objects with the same name in the controller API ([#6579](https://github.com/cyberbotics/webots/pull/6579))
8 changes: 6 additions & 2 deletions docs/reference/robot.md
Original file line number Diff line number Diff line change
Expand Up @@ -766,11 +766,12 @@ WbDeviceTag wb_robot_get_device(const char *name);
namespace webots {
class Robot {
Accelerometer *getAccelerometer(const std::string &name);
Altimeter *getAltimeter(const std::string &name);
Altimeter *getAltimeter(const std::string &name);
Brake *getBrake(const std::string &name);
Camera *getCamera(const std::string &name);
Compass *getCompass(const std::string &name);
Connector *getConnector(const std::string &name);
Device *getDevice(const std::string &name);
Display *getDisplay(const std::string &name);
DistanceSensor *getDistanceSensor(const std::string &name);
Emitter *getEmitter(const std::string &name);
Expand Down Expand Up @@ -826,6 +827,7 @@ public class Robot {
public Camera getCamera(String name);
public Compass getCompass(String name);
public Connector getConnector(String name);
public Device getDevice(String name);
public Display getDisplay(String name);
public DistanceSensor getDistanceSensor(String name);
public Emitter getEmitter(String name);
Expand Down Expand Up @@ -874,7 +876,7 @@ Devices are available through their services.

*get a unique identifier to a device*

The `wb_robot_get_device` function (available in C, Python and MATLAB) returns a unique identifier for a device corresponding to a specified `name`.
The `wb_robot_get_device` function returns a unique identifier for a device corresponding to a specified `name`.
For example, if a robot contains a [DistanceSensor](distancesensor.md) node whose `name` field is "ds1", the function will return the unique identifier of that device.
This `WbDeviceTag` identifier will be used subsequently for enabling, sending commands to, or reading data from this device.
If the specified device is not found, the function returns 0 in C and MATLAB or `None` in Python.
Expand All @@ -885,6 +887,8 @@ Depending on the called function, this object can be an instance of a `Device` s
For example, if a robot contains a [DistanceSensor](distancesensor.md) node whose `name` field is "ds1", the function `getDistanceSensor` will return a reference to a [DistanceSensor](distancesensor.md) object.
If the specified device is not found, the function returns `NULL` in C++ or `null` in Java.

Note that if any two devices share the same name, `wb_robot_get_device` will return the first one it finds. In order to distinguish between devices with the same name, users should consider iterating over a robot's devices using `wb_robot_get_device_by_index` and `wb_robot_get_number_of_devices`.

---

#### `wb_robot_get_device_by_index`
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Accelerometer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Accelerometer : public Device {
public:
explicit Accelerometer(const std::string &name) : Device(name) {} // Use Robot::getAccelerometer() instead
explicit Accelerometer(WbDeviceTag tag) : Device(tag) {}
virtual ~Accelerometer() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Altimeter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Altimeter : public Device {
public:
explicit Altimeter(const std::string &name) : Device(name) {} // Use Robot::getAltimeter instead
explicit Altimeter(WbDeviceTag tag) : Device(tag) {}
virtual ~Altimeter() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Brake.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace webots {
Device(name),
motor(NULL),
positionSensor(NULL) {} // Use Robot::getBrake() instead
explicit Brake(WbDeviceTag tag) : Device(tag), motor(NULL), positionSensor(NULL) {}
virtual ~Brake() {}
Type getType() const;
void setDampingConstant(double dampingConstant) const;
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace webots {
class Camera : public Device {
public:
explicit Camera(const std::string &name) : Device(name) {} // Use Robot::getCamera() instead
explicit Camera(WbDeviceTag tag) : Device(tag) {}
virtual ~Camera() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Compass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Compass : public Device {
public:
explicit Compass(const std::string &name) : Device(name) {} // Use Robot::getCompass() instead
explicit Compass(WbDeviceTag tag) : Device(tag) {}
virtual ~Compass() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Connector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Connector : public Device {
public:
explicit Connector(const std::string &name) : Device(name) {} // Use Robot::getConnector() instead
explicit Connector(WbDeviceTag tag) : Device(tag) {}
virtual ~Connector() {}
virtual void enablePresence(int samplingPeriod);
virtual void disablePresence();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace webots {

protected:
explicit Device(const std::string &name);
explicit Device(WbDeviceTag tag);

private:
WbDeviceTag tag;
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Display.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace webots {
public:
enum { RGB = 3, RGBA, ARGB, BGRA, ABGR };
explicit Display(const std::string &name) : Device(name) {} // Use Robot::getDisplay() instead
explicit Display(WbDeviceTag tag) : Device(tag) {}
virtual ~Display() {}
int getWidth() const;
int getHeight() const;
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/DistanceSensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace webots {
typedef enum { GENERIC = 0, INFRA_RED, SONAR, LASER } Type;

explicit DistanceSensor(const std::string &name) : Device(name) {} // Use Robot::getDistanceSensor() instead
explicit DistanceSensor(WbDeviceTag tag) : Device(tag) {}
virtual ~DistanceSensor() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Emitter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Emitter : public Device {
public:
explicit Emitter(const std::string &name) : Device(name) {} // Use Robot::getEmitter() instead
explicit Emitter(WbDeviceTag tag) : Device(tag) {}
virtual ~Emitter() {}
enum { CHANNEL_BROADCAST = -1 };
virtual int send(const void *data, int size);
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/GPS.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace webots {
typedef enum { LOCAL = 0, WGS84 } CoordinateSystem;

explicit GPS(const std::string &name) : Device(name) {} // Use Robot::getGPS() instead
explicit GPS(WbDeviceTag tag) : Device(tag) {}
virtual ~GPS() {}

virtual void enable(int samplingPeriod);
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Gyro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Gyro : public Device {
public:
explicit Gyro(const std::string &name) : Device(name) {} // Use Robot::getGyro() instead
explicit Gyro(WbDeviceTag tag) : Device(tag) {}
virtual ~Gyro() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/InertialUnit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class InertialUnit : public Device {
public:
explicit InertialUnit(const std::string &name) : Device(name) {} // Use Robot::getInertialUnit() instead
explicit InertialUnit(WbDeviceTag tag) : Device(tag) {}
virtual ~InertialUnit() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/LED.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class LED : public Device {
public:
explicit LED(const std::string &name) : Device(name) {} // Use Robot::getLED() instead
explicit LED(WbDeviceTag tag) : Device(tag) {}
virtual ~LED() {}
virtual void set(int value);
int get() const;
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Lidar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace webots {
class Lidar : public Device {
public:
explicit Lidar(const std::string &name) : Device(name) {} // Use Robot::getLidar() instead
explicit Lidar(WbDeviceTag tag) : Device(tag) {}
virtual ~Lidar() {}
virtual void enable(int samplingPeriod);
void enablePointCloud();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/LightSensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class LightSensor : public Device {
public:
explicit LightSensor(const std::string &name) : Device(name) {} // Use Robot::getLightSensor() instead
explicit LightSensor(WbDeviceTag tag) : Device(tag) {}
virtual ~LightSensor() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Motor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace webots {
Device(name),
brake(NULL),
positionSensor(NULL) {} // Use Robot::getMotor() instead
explicit Motor(WbDeviceTag tag) : Device(tag), brake(NULL), positionSensor(NULL) {}
virtual ~Motor() {}

virtual void setPosition(double position);
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Pen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Pen : public Device {
public:
explicit Pen(const std::string &name) : Device(name) {} // Use Robot::getPen() instead
explicit Pen(WbDeviceTag tag) : Device(tag) {}
virtual ~Pen() {}
virtual void write(bool write);
virtual void setInkColor(int color, double density);
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/PositionSensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace webots {
Device(name),
brake(NULL),
motor(NULL) {} // Use Robot::getPositionSensor() instead
explicit PositionSensor(WbDeviceTag tag) : Device(tag), brake(NULL), motor(NULL) {}
virtual ~PositionSensor() {}
virtual void enable(int samplingPeriod); // milliseconds
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Radar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace webots {
class Radar : public Device {
public:
explicit Radar(const std::string &name) : Device(name) {} // Use Robot::getRadar() instead
explicit Radar(WbDeviceTag tag) : Device(tag) {}
virtual ~Radar() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/RangeFinder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class RangeFinder : public Device {
public:
explicit RangeFinder(const std::string &name) : Device(name) {} // Use Robot::getRangeFinder() instead
explicit RangeFinder(WbDeviceTag tag) : Device(tag) {}
virtual ~RangeFinder() {}
virtual void enable(int samplingPeriod);
virtual void disable();
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Receiver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Receiver : public Device {
public:
explicit Receiver(const std::string &name) : Device(name) {} // Use Robot::getReceiver() instead
explicit Receiver(WbDeviceTag tag) : Device(tag) {}
virtual ~Receiver() {}
enum { CHANNEL_BROADCAST = -1 };
virtual void enable(int samplingPeriod);
Expand Down
52 changes: 27 additions & 25 deletions include/controller/cpp/webots/Robot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <iostream>
#include <vector>

#include "../../c/webots/types.h"

namespace webots {
class Accelerometer;
class Altimeter;
Expand Down Expand Up @@ -141,31 +143,31 @@ namespace webots {

protected:
static Robot *cInstance;
virtual Accelerometer *createAccelerometer(const std::string &name) const;
virtual Altimeter *createAltimeter(const std::string &name) const;
virtual Brake *createBrake(const std::string &name) const;
virtual Camera *createCamera(const std::string &name) const;
virtual Compass *createCompass(const std::string &name) const;
virtual Connector *createConnector(const std::string &name) const;
virtual Display *createDisplay(const std::string &name) const;
virtual DistanceSensor *createDistanceSensor(const std::string &name) const;
virtual Emitter *createEmitter(const std::string &name) const;
virtual GPS *createGPS(const std::string &name) const;
virtual Gyro *createGyro(const std::string &name) const;
virtual InertialUnit *createInertialUnit(const std::string &name) const;
virtual LED *createLED(const std::string &name) const;
virtual Lidar *createLidar(const std::string &name) const;
virtual LightSensor *createLightSensor(const std::string &name) const;
virtual Motor *createMotor(const std::string &name) const;
virtual Pen *createPen(const std::string &name) const;
virtual PositionSensor *createPositionSensor(const std::string &name) const;
virtual Radar *createRadar(const std::string &name) const;
virtual RangeFinder *createRangeFinder(const std::string &name) const;
virtual Receiver *createReceiver(const std::string &name) const;
virtual Skin *createSkin(const std::string &name) const;
virtual Speaker *createSpeaker(const std::string &name) const;
virtual TouchSensor *createTouchSensor(const std::string &name) const;
virtual VacuumGripper *createVacuumGripper(const std::string &name) const;
virtual Accelerometer *createAccelerometer(WbDeviceTag tag) const;
virtual Altimeter *createAltimeter(WbDeviceTag tag) const;
virtual Brake *createBrake(WbDeviceTag tag) const;
virtual Camera *createCamera(WbDeviceTag tag) const;
virtual Compass *createCompass(WbDeviceTag tag) const;
virtual Connector *createConnector(WbDeviceTag tag) const;
virtual Display *createDisplay(WbDeviceTag tag) const;
virtual DistanceSensor *createDistanceSensor(WbDeviceTag tag) const;
virtual Emitter *createEmitter(WbDeviceTag tag) const;
virtual GPS *createGPS(WbDeviceTag tag) const;
virtual Gyro *createGyro(WbDeviceTag tag) const;
virtual InertialUnit *createInertialUnit(WbDeviceTag tag) const;
virtual LED *createLED(WbDeviceTag tag) const;
virtual Lidar *createLidar(WbDeviceTag tag) const;
virtual LightSensor *createLightSensor(WbDeviceTag tag) const;
virtual Motor *createMotor(WbDeviceTag tag) const;
virtual Pen *createPen(WbDeviceTag tag) const;
virtual PositionSensor *createPositionSensor(WbDeviceTag tag) const;
virtual Radar *createRadar(WbDeviceTag tag) const;
virtual RangeFinder *createRangeFinder(WbDeviceTag tag) const;
virtual Receiver *createReceiver(WbDeviceTag tag) const;
virtual Skin *createSkin(WbDeviceTag tag) const;
virtual Speaker *createSpeaker(WbDeviceTag tag) const;
virtual TouchSensor *createTouchSensor(WbDeviceTag tag) const;
virtual VacuumGripper *createVacuumGripper(WbDeviceTag tag) const;

private:
Keyboard *mKeyboard;
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Skin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Skin : public Device {
public:
explicit Skin(const std::string &name) : Device(name) {}
explicit Skin(WbDeviceTag tag) : Device(tag) {}
virtual ~Skin() {}
void setBoneOrientation(int index, const double orientation[4], bool absolute);
void setBonePosition(int index, const double position[3], bool absolute);
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/Speaker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class Speaker : public Device {
public:
explicit Speaker(const std::string &name) : Device(name) {} // Use Robot::getSpeaker() instead
explicit Speaker(WbDeviceTag tag) : Device(tag) {}
virtual ~Speaker() {}
static void playSound(Speaker *left, Speaker *right, const std::string &sound, double volume, double pitch, double balance,
bool loop);
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/TouchSensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace webots {
typedef enum { BUMPER = 0, FORCE, FORCE3D } Type;

explicit TouchSensor(const std::string &name) : Device(name) {} // Use Robot::getTouchSensor() instead
explicit TouchSensor(WbDeviceTag tag) : Device(tag) {}
virtual ~TouchSensor() {}

virtual void enable(int samplingPeriod);
Expand Down
1 change: 1 addition & 0 deletions include/controller/cpp/webots/VacuumGripper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace webots {
class VacuumGripper : public Device {
public:
explicit VacuumGripper(const std::string &name) : Device(name) {} // Use Robot::getVacuumGripper() instead
explicit VacuumGripper(WbDeviceTag tag) : Device(tag) {}
virtual ~VacuumGripper() {}
virtual void enablePresence(int samplingPeriod);
virtual void disablePresence();
Expand Down
2 changes: 1 addition & 1 deletion lib/controller/python/controller/robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def __init__(self):
if type == Node.ACCELEROMETER:
self.devices[name] = Accelerometer(tag)
elif type == Node.ALTIMETER:
self.devices[name] = Altimeter(name)
self.devices[name] = Altimeter(tag)
elif type == Node.BRAKE:
self.devices[name] = Brake(tag)
elif type == Node.CAMERA:
Expand Down
4 changes: 4 additions & 0 deletions src/controller/cpp/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ Device::Device(const string &deviceName) : name(deviceName) {
tag = wb_robot_get_device(name.c_str());
}

Device::Device(WbDeviceTag deviceTag) : tag(deviceTag) {
name = wb_device_get_name(deviceTag);
}

int Device::getNodeType() const {
return wb_device_get_node_type(tag);
}
Expand Down
Loading

0 comments on commit a01ffad

Please sign in to comment.