See More

// Copyright 1996-2021 Cyberbotics Ltd. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /*******************************************************************************************************/ /* Description: Swig interface which maps the OO C++ files into a python module called "controller" */ /*******************************************************************************************************/ %module(threads=1) controller %begin %{ #define SWIG_PYTHON_2_UNICODE %} %pythonbegin %{ import sys import os if os.name == 'nt' and sys.version_info >= (3, 8): # we need to explicitly list the folders containing the DLLs webots_home = os.environ['WEBOTS_HOME'] os.add_dll_directory(os.path.join(webots_home, 'lib', 'controller')) # MSYS2_HOME should be set by Webots or ~/.bash_profile # if not set, we are in the case of an extern controller and a regularly installed version of Webots msys64_root = os.environ['MSYS2_HOME'] if 'MSYS2_HOME' in os.environ else os.path.join(webots_home, 'msys64') cpp_folder = os.path.join(msys64_root, 'mingw64', 'bin', 'cpp') if not os.path.isdir(cpp_folder): # development environment cpp_folder = os.path.join(msys64_root, 'mingw64', 'bin') os.add_dll_directory(cpp_folder) %} %{ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; %} //---------------------------------------------------------------------------------------------- // Miscellaneous - controller module's level //---------------------------------------------------------------------------------------------- %thread webots::Robot::step(int duration); %nothreadblock; //handling std::string %include "std_string.i" %include "typemaps.i" %rename ("__internalGetLookupTableSize") getLookupTableSize; // manage double arrays %typemap(out) const double * { int len = 3; const string test("$name"); if (test == "getSFVec2f" || test == "getMFVec2f") len = 2; else if (test == "getSFRotation" || test == "getQuaternion") len = 4; else if (test == "getVelocity") len = 6; else if (test == "getOrientation" || test == "virtualRealityHeadsetGetOrientation") len = 9; else if (test == "getPose") len = 16; $result = PyList_New(len); for (int i = 0; i < len; ++i) PyList_SetItem($result, i, PyFloat_FromDouble($1[i])); } %typemap(out) const double *getLookupTable { const int len = arg1->getLookupTableSize()*3; $result = PyList_New(len); for (int i = 0; i < len; ++i) PyList_SetItem($result, i, PyFloat_FromDouble($1[i])); } %typemap(in) const double [ANY] { if (!PyList_Check($input)) { PyErr_SetString(PyExc_TypeError, "in method '$name', expected 'PyList'\n"); return NULL; } const int len = PyList_Size($input); $1 = (double*)malloc(len * sizeof(double)); for (int i = 0; i < len; ++i) $1[i] = PyFloat_AsDouble(PyList_GetItem($input, i)); } %typemap(freearg) const double [ANY] { free($1); } %typemap(in) const int * { if (!PyList_Check($input)) { PyErr_SetString(PyExc_TypeError, "in method '$name', expected 'PyList'\n"); return NULL; } const int len = PyList_Size($input); $1 = (int*)malloc(len * sizeof(int)); for (int i = 0; i < len; ++i) $1[i] = PyInt_AsLong(PyList_GetItem($input, i)); } %typemap(freearg) const int * { free($1); } //---------------------------------------------------------------------------------------------- // ANSI Support //---------------------------------------------------------------------------------------------- %pythoncode %{ class AnsiCodes(object): RESET = u'\u001b[0m' BOLD = u'\u001b[1m' UNDERLINE = u'\u001b[4m' BLACK_BACKGROUND = u'\u001b[40m' RED_BACKGROUND = u'\u001b[41m' GREEN_BACKGROUND = u'\u001b[42m' YELLOW_BACKGROUND = u'\u001b[43m' BLUE_BACKGROUND = u'\u001b[44m' MAGENTA_BACKGROUND = u'\u001b[45m' CYAN_BACKGROUND = u'\u001b[46m' WHITE_BACKGROUND = u'\u001b[47m' BLACK_FOREGROUND = u'\u001b[30m' RED_FOREGROUND = u'\u001b[31m' GREEN_FOREGROUND = u'\u001b[32m' YELLOW_FOREGROUND = u'\u001b[33m' BLUE_FOREGROUND = u'\u001b[34m' MAGENTA_FOREGROUND = u'\u001b[35m' CYAN_FOREGROUND = u'\u001b[36m' WHITE_FOREGROUND = u'\u001b[37m' CLEAR_SCREEN = u'\u001b[2J' %} //---------------------------------------------------------------------------------------------- // Device //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Accelerometer //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Altimeter //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Brake //---------------------------------------------------------------------------------------------- %include %extend webots::Brake { %pythoncode %{ def getMotor(self): try: return self.__motor except AttributeError: self.__motor = Robot.internalGetDeviceFromTag(self.getMotorTag()) return self.__motor def getPositionSensor(self): try: return self.instance except AttributeError: self.__positionSensor = Robot.internalGetDeviceFromTag(self.getPositionSensorTag()) return self.__positionSensor %} } //---------------------------------------------------------------------------------------------- // Camera //---------------------------------------------------------------------------------------------- %rename WbCameraRecognitionObject CameraRecognitionObject; %include %extend WbCameraRecognitionObject { PyObject *get_position() { const double *position = $self->position; SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyList_New(3); PyList_SetItem(ret, 0, PyFloat_FromDouble(position[0])); PyList_SetItem(ret, 1, PyFloat_FromDouble(position[1])); PyList_SetItem(ret, 2, PyFloat_FromDouble(position[2])); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } PyObject *get_orientation() { const double *orientation = $self->orientation; SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyList_New(4); PyList_SetItem(ret, 0, PyFloat_FromDouble(orientation[0])); PyList_SetItem(ret, 1, PyFloat_FromDouble(orientation[1])); PyList_SetItem(ret, 2, PyFloat_FromDouble(orientation[2])); PyList_SetItem(ret, 3, PyFloat_FromDouble(orientation[3])); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } PyObject *get_size() { const double *size = $self->size; SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyList_New(2); PyList_SetItem(ret, 0, PyFloat_FromDouble(size[0])); PyList_SetItem(ret, 1, PyFloat_FromDouble(size[1])); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } PyObject *get_position_on_image() { const int *position_on_image = $self->position_on_image; SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyList_New(2); PyList_SetItem(ret, 0, PyInt_FromLong(position_on_image[0])); PyList_SetItem(ret, 1, PyInt_FromLong(position_on_image[1])); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } PyObject *get_size_on_image() { const int *size_on_image = $self->size_on_image; SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyList_New(2); PyList_SetItem(ret, 0, PyInt_FromLong(size_on_image[0])); PyList_SetItem(ret, 1, PyInt_FromLong(size_on_image[1])); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } PyObject *get_colors() { const double *colors = $self->colors; const int number_of_color = $self->number_of_colors; SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyList_New(3 * number_of_color); for (int i = 0; i < 3 * number_of_color; ++i) PyList_SetItem(ret, i, PyFloat_FromDouble(colors[i])); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } PyObject *get_id() { SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyInt_FromLong($self->id); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } PyObject *get_number_of_colors() { SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyInt_FromLong($self->number_of_colors); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } PyObject *get_model() { return PyBytes_FromStringAndSize($self->model, strlen($self->model)); } }; %typemap(out) unsigned char * { const int width = arg1->getWidth(); const int height = arg1->getHeight(); if ($1) $result = PyBytes_FromStringAndSize((const char*)$1, 4 * width * height); else $result = Py_None; } %extend webots::Camera { PyObject *getImageArray() { const unsigned char *im = $self->getImage(); const int width = $self->getWidth(); const int height = $self->getHeight(); PyObject *ret = Py_None; if (im) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; ret = PyList_New(width); for (int x = 0; x < width; ++x) { PyObject *dim2 = PyList_New(height); PyList_SetItem(ret, x, dim2); for (int y = 0; y < height; ++y) { PyObject *dim3 = PyList_New(3); PyList_SetItem(dim2, y, dim3); for (int ch = 0; ch < 3; ++ch) PyList_SetItem(dim3, ch, PyInt_FromLong((unsigned int)(im[4 * (x + y * width) + 2 - ch]))); } } SWIG_PYTHON_THREAD_END_BLOCK; } return ret; } static PyObject *imageGetRed(PyObject *im, int width, int x, int y) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; if (!PyString_Check(im)) { PyErr_SetString(PyExc_TypeError, "in method 'Camera_imageGetRed', argument 2 of type 'PyString'\n"); SWIG_PYTHON_THREAD_END_BLOCK; return NULL; } const unsigned char *s = (unsigned char*)PyString_AsString(im); PyObject *ret = PyInt_FromLong(s[4 * (y * width + x) + 2]); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } static PyObject *imageGetGreen(PyObject *im, int width, int x, int y) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; if (!PyString_Check(im)) { PyErr_SetString(PyExc_TypeError, "in method 'Camera_imageGetGreen', argument 2 of type 'PyString'\n"); SWIG_PYTHON_THREAD_END_BLOCK; return NULL; } const unsigned char *s = (unsigned char*)PyString_AsString(im); PyObject *ret = PyInt_FromLong(s[4 * (y * width + x) + 1]); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } static PyObject *imageGetBlue(PyObject *im, int width, int x, int y) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; if (!PyString_Check(im)) { PyErr_SetString(PyExc_TypeError, "in method 'Camera_imageGetBlue', argument 2 of type 'PyString'\n"); SWIG_PYTHON_THREAD_END_BLOCK; return NULL; } const unsigned char *s = (unsigned char*)PyString_AsString(im); PyObject *ret = PyInt_FromLong(s[4 * (y * width + x)]); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } static PyObject *imageGetGray(PyObject *im, int width, int x, int y) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; if (!PyString_Check(im)) { PyErr_SetString(PyExc_TypeError, "in method 'Camera_imageGetGrey', argument 2 of type 'PyString'\n"); SWIG_PYTHON_THREAD_END_BLOCK; return NULL; } const unsigned char *s = (unsigned char*)PyString_AsString(im); PyObject *ret = PyInt_FromLong((s[4 * (y * width + x)] + s[4 * (y * width + x) + 1] + s[4 * (y * width + x) + 2]) / 3); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } static PyObject *imageGetGrey(PyObject *im, int width, int x, int y) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; if (!PyString_Check(im)) { PyErr_SetString(PyExc_TypeError, "in method 'Camera_imageGetGrey', argument 2 of type 'PyString'\n"); SWIG_PYTHON_THREAD_END_BLOCK; return NULL; } const unsigned char *s = (unsigned char*)PyString_AsString(im); PyObject *ret = PyInt_FromLong((s[4 * (y * width + x)] + s[4 * (y * width + x) + 1] + s[4 * (y * width + x) + 2]) / 3); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } webots::CameraRecognitionObject getRecognitionObject(int index) const { const webots::CameraRecognitionObject *objects = $self->getRecognitionObjects(); return objects[index]; } %pythoncode %{ def getRecognitionObjects(self): ret = [] for i in range(self.getRecognitionNumberOfObjects()): ret.append(self.getRecognitionObject(i)) return ret %} PyObject *getRecognitionSegmentationImageArray() { const unsigned char *im = $self->getRecognitionSegmentationImage(); const int width = $self->getWidth(); const int height = $self->getHeight(); PyObject *ret = Py_None; if (im) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; ret = PyList_New(width); for (int x = 0; x < width; ++x) { PyObject *dim2 = PyList_New(height); PyList_SetItem(ret, x, dim2); for (int y = 0; y < height; ++y) { PyObject *dim3 = PyList_New(3); PyList_SetItem(dim2, y, dim3); for (int ch = 0; ch < 3; ++ch) PyList_SetItem(dim3, ch, PyInt_FromLong((unsigned int)(im[4 * (x + y * width) + 2 - ch]))); } } SWIG_PYTHON_THREAD_END_BLOCK; } return ret; } }; %include %typemap(out) unsigned char *; //---------------------------------------------------------------------------------------------- // Compass //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Connector //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Display //---------------------------------------------------------------------------------------------- %typemap(in) const void *(bool need_to_delete) { if (!PyList_Check($input) && !PyString_Check($input)) { PyErr_SetString(PyExc_TypeError, "expected 'PyList' or 'PyString'\n"); return NULL; } if (PyList_Check($input)) { const int len1 = PyList_Size($input); PyObject *l2 = PyList_GetItem($input, 0); if (!PyList_Check(l2)) { PyErr_SetString(PyExc_TypeError, "expected 'PyList' of 'PyList'\n"); return NULL; } const int len2 = PyList_Size(l2); PyObject *l3 = PyList_GetItem(l2, 0); if (!PyList_Check(l3)) { PyErr_SetString(PyExc_TypeError, "expected 'PyList' of 'PyList' of 'PyList'\n"); return NULL; } const int len3 = PyList_Size(l3); $1 = (void *)malloc(len1 * len2 * len3 * sizeof(unsigned char)); need_to_delete = true; for (int i = 0; i < len1; ++i) for (int j = 0; j < len2; ++j) for (int k = 0; k < len3; ++k) ((unsigned char *)$1)[(j * len1 * len3) + (i * len3) + k] = (unsigned char) PyInt_AsLong(PyList_GetItem(PyList_GetItem(PyList_GetItem($input, i), j), k)); } else { // PyString case $1 = PyString_AsString($input); need_to_delete = false; } } %typemap(freearg) const void * { if (need_to_delete$argnum) free($1); } %rename (__internalImageNew) imageNew(int width, int height, const void *data, int format) const; %rename (__internalDrawPolygon) drawPolygon(const int *x, const int *y, int size); %rename (__internalFillPolygon) fillPolygon(const int *x, const int *y, int size); %extend webots::Display { %pythoncode %{ def imageNew(self, data, format, width=None, height=None): if isinstance(data, list): return self.__internalImageNew(len(data), len(data[0]), data, format) elif width is None or height is None: raise TypeError('imageNew : width and height must be given if data is not a list') else: return self.__internalImageNew(width, height, data, format) def drawPolygon(self, x, y): self.__internalDrawPolygon(x, y, min(len(x), len(y))) def fillPolygon(self, x, y): self.__internalFillPolygon(x, y, min(len(x), len(y))) %} } %include %include //---------------------------------------------------------------------------------------------- // Distance sensor //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Emitter //---------------------------------------------------------------------------------------------- %typemap(in) (const void *data, int size) { $1 = PyString_AsString($input); $2 = PyString_Size($input); } %include %typemap(in) (const void *data, int size); //---------------------------------------------------------------------------------------------- // Field //---------------------------------------------------------------------------------------------- %ignore webots::Field::findField(WbFieldRef ref); %ignore webots::Field::cleanup(); %include //---------------------------------------------------------------------------------------------- // GPS //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Gyro //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // InertialUnit //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Joystick //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Keyboard //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // LED //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Lidar //---------------------------------------------------------------------------------------------- %rename WbLidarPoint LidarPoint; %include %typemap(out) float * { const int width = arg1->getHorizontalResolution(); const int height = arg1->getNumberOfLayers(); const string functionName("$name"); int len; if (functionName == "getLayerRangeImage") len = width; else len = width * height; if ($1) { $result = PyList_New(len); for (int x = 0; x < len; ++x) PyList_SetItem($result, x, PyFloat_FromDouble($1[x])); } else $result = Py_None; } %ignore webots::Lidar::getPointCloud(); %ignore webots::Lidar::getLayerPointCloud(); %extend webots::Lidar { PyObject *__getPointCloudBuffer(int layer) const { const char *points = layer < 0 ? (const char *)$self->getPointCloud() : (const char *)$self->getLayerPointCloud(layer); const int numberOfPoints = layer < 0 ? $self->getNumberOfPoints() : $self->getHorizontalResolution(); const int size = numberOfPoints * sizeof(WbLidarPoint); return PyBytes_FromStringAndSize(points, size); } PyObject* __getPointCloudList(int layer) const { const WbLidarPoint *rawPoints = layer < 0 ? $self->getPointCloud() : $self->getLayerPointCloud(layer); const int size = layer < 0 ? $self->getNumberOfPoints() : $self->getHorizontalResolution(); SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *points = PyList_New(size); for (int i = 0; i < size; i++) { PyObject *value = SWIG_NewPointerObj(SWIG_as_voidptr(&rawPoints[i]), $descriptor(WbLidarPoint *), 0); PyList_SetItem(points, i, value); } SWIG_PYTHON_THREAD_END_BLOCK; return points; } %pythoncode %{ import sys def getPointCloud(self, data_type='list'): if data_type == 'list': return self.__getPointCloudList(-1) elif data_type == 'buffer': return self.__getPointCloudBuffer(-1) else: sys.stderr.write("Error: `data_type` cannot be `{}`! Supported values are 'list' and 'buffer'.\n".format(data_type)) return None def getLayerPointCloud(self, layer, data_type='list'): if data_type == 'list': return self.__getPointCloudList(layer) elif data_type == 'buffer': return self.__getPointCloudBuffer(layer) else: sys.stderr.write("Error: `data_type` cannot be `{}`! Supported values are 'list' and 'buffer'.\n".format(data_type)) return None %} PyObject *getRangeImageArray() { const float *im = $self->getRangeImage(); const int width = $self->getHorizontalResolution(); const int height = $self->getNumberOfLayers(); PyObject *ret = Py_None; if (im) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; ret = PyList_New(width); for (int x = 0; x < width; ++x) { PyObject *dim2 = PyList_New(height); PyList_SetItem(ret, x, dim2); for (int y = 0; y < height; ++y) { PyObject *v = PyFloat_FromDouble(im[x + y * width]); PyList_SetItem(dim2, y, v); } } SWIG_PYTHON_THREAD_END_BLOCK; } return ret; } }; %include %typemap(out) float *; //---------------------------------------------------------------------------------------------- // LightSensor //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Motion //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Motor //---------------------------------------------------------------------------------------------- %include %extend webots::Motor { %pythoncode %{ def getBrake(self): try: return self.__brake except AttributeError: self.__brake = Robot.internalGetDeviceFromTag(self.getBrakeTag()) return self.__brake def getPositionSensor(self): try: return self.__positionSensor except AttributeError: self.__positionSensor = Robot.internalGetDeviceFromTag(self.getPositionSensorTag()) return self.__positionSensor %} } //---------------------------------------------------------------------------------------------- // Mouse //---------------------------------------------------------------------------------------------- %rename WbMouseState MouseState; %include %include //---------------------------------------------------------------------------------------------- // Node //---------------------------------------------------------------------------------------------- %rename WbContactPoint ContactPoint; %include %extend WbContactPoint { PyObject *get_point() { const double *point = $self->point; SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyList_New(3); PyList_SetItem(ret, 0, PyFloat_FromDouble(point[0])); PyList_SetItem(ret, 1, PyFloat_FromDouble(point[1])); PyList_SetItem(ret, 2, PyFloat_FromDouble(point[2])); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } PyObject *get_node_id() { const double orientation = $self->node_id; SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyInt_FromLong(orientation); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } %pythoncode %{ @property def point(self): return self.get_point() %} }; %ignore webots::Node::findNode(WbNodeRef ref); %ignore webots::Node::cleanup(); %rename ("getContactPointsPrivate") webots::Node::getContactPoints; %apply int *OUTPUT { int *size }; %extend webots::Node { %pythoncode %{ def __eq__(self, other): if self is None and other is None: return True elif self is None or other is None: return False elif self.getId() == other.getId(): return True return False def __ne__(self, other): return not self.__eq__(other) def getContactPoints(self, includeDescendants=False): point_data = self.getContactPointsPrivate(includeDescendants) if not point_data: return [] ret = [] points, size = point_data for i in range(size): ret.append(self.getContactPointFromList(points, i)) return ret %} webots::ContactPoint* getContactPointFromList(ContactPoint* points, int index) const { return &points[index]; } }; %include //---------------------------------------------------------------------------------------------- // Pen //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // PositionSensor //---------------------------------------------------------------------------------------------- %include %extend webots::PositionSensor { %pythoncode %{ def getBrake(self): try: return self.__brake except AttributeError: self.__brake = Robot.internalGetDeviceFromTag(self.getBrakeTag()) return self.__brake def getMotor(self): try: return self.__motor except AttributeError: self.__motor = Robot.internalGetDeviceFromTag(self.getMotorTag()) return self.__motor %} } //---------------------------------------------------------------------------------------------- // Radar //---------------------------------------------------------------------------------------------- %rename WbRadarTarget RadarTarget; %include %ignore webots::Lidar::getTargets(); %extend webots::Radar { webots::RadarTarget getTarget(int index) const { const webots::RadarTarget *targets = $self->getTargets(); return targets[index]; } %pythoncode %{ def getTargets(self): ret = [] for i in range(self.getNumberOfTargets()): ret.append(self.getTarget(i)) return ret %} }; %include //---------------------------------------------------------------------------------------------- // RangeFinder //---------------------------------------------------------------------------------------------- %extend webots::RangeFinder { PyObject *__getRangeImageList() { const float *im = $self->getRangeImage(); const int width = $self->getWidth(); const int height = $self->getHeight(); const int len = width * height; if (im) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyObject *ret = PyList_New(len); for (int x = 0; x < len; ++x) PyList_SetItem(ret, x, PyFloat_FromDouble(im[x])); SWIG_PYTHON_THREAD_END_BLOCK; return ret; } else { return Py_None; } } PyObject *__getRangeImageBuffer() { const float *im = $self->getRangeImage(); const char *im_bytes = (const char *)im; const int size = $self->getWidth() * $self->getHeight() * sizeof(float); return PyBytes_FromStringAndSize(im_bytes, size); } PyObject *getRangeImageArray() { const float *im = $self->getRangeImage(); const int width = $self->getWidth(); const int height = $self->getHeight(); PyObject *ret = Py_None; if (im) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; ret = PyList_New(width); for (int x = 0; x < width; ++x) { PyObject *dim2 = PyList_New(height); PyList_SetItem(ret, x, dim2); for (int y = 0; y < height; ++y) { PyObject *v = PyFloat_FromDouble(im[x + y * width]); PyList_SetItem(dim2, y, v); } } SWIG_PYTHON_THREAD_END_BLOCK; } return ret; } %pythoncode %{ def getRangeImage(self, data_type='list'): if data_type == 'list': return self.__getRangeImageList() elif data_type == 'buffer': return self.__getRangeImageBuffer() else: print("Error: `data_type` cannot be `{}`! Supported values are 'list' and 'buffer'.".format(data_type), file=sys.stderr) return None %} static PyObject *rangeImageGetValue(PyObject *im, double minRange, double maxRange, int width, int x, int y) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; if (!PyList_Check(im)) { PyErr_SetString(PyExc_TypeError, "in method 'RangeFinder_rangeImageGetValue', argument 2 of type 'PyList'\n"); SWIG_PYTHON_THREAD_END_BLOCK; return NULL; } PyObject *value = PyList_GetItem(im, y * width + x); if (!PyFloat_Check(value)) { PyErr_SetString(PyExc_TypeError, "in method 'RangeFinder_rangeImageGetValue', argument 2 of type 'PyList' of 'PyFloat'\n"); SWIG_PYTHON_THREAD_END_BLOCK; return NULL; } fprintf(stderr, "Warning: RangeFinder.rangeImageGetValue is deprecated, please use RangeFinder.rangeImageGetDepth instead\n"); // inform Python runtime that the object is used somewhere else // this prevents crashes when updating the range image internal list Py_INCREF(value); SWIG_PYTHON_THREAD_END_BLOCK; return value; } static PyObject *rangeImageGetDepth(PyObject *im, int width, int x, int y) { SWIG_PYTHON_THREAD_BEGIN_BLOCK; if (!PyList_Check(im)) { PyErr_SetString(PyExc_TypeError, "in method 'RangeFinder_rangeImageGetDepth', argument 2 of type 'PyList'\n"); SWIG_PYTHON_THREAD_END_BLOCK; return NULL; } PyObject *value = PyList_GetItem(im, y * width + x); if (!PyFloat_Check(value)) { PyErr_SetString(PyExc_TypeError, "in method 'RangeFinder_rangeImageGetDepth', argument 2 of type 'PyList' of 'PyFloat'\n"); SWIG_PYTHON_THREAD_END_BLOCK; return NULL; } // inform Python runtime that the object is used somewhere else // this prevents crashes when updating the range image internal list Py_INCREF(value); SWIG_PYTHON_THREAD_END_BLOCK; return value; } }; %include %typemap(out) float *; //---------------------------------------------------------------------------------------------- // Receiver //---------------------------------------------------------------------------------------------- %typemap(out) const void * { $result = PyBytes_FromStringAndSize((const char*) $1, arg1->getDataSize()); } %include %typemap(out) const void *; //---------------------------------------------------------------------------------------------- // Skin //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Speaker //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // TouchSensor //---------------------------------------------------------------------------------------------- %include //---------------------------------------------------------------------------------------------- // Robot //---------------------------------------------------------------------------------------------- %ignore webots::Robot::getAccelerometer(const std::string &name); %ignore webots::Robot::getAltimeter(const std::string &name); %ignore webots::Robot::getBrake(const std::string &name); %ignore webots::Robot::getCamera(const std::string &name); %ignore webots::Robot::getCompass(const std::string &name); %ignore webots::Robot::getConnector(const std::string &name); %ignore webots::Robot::getDisplay(const std::string &name); %ignore webots::Robot::getDistanceSensor(const std::string &name); %ignore webots::Robot::getEmitter(const std::string &name); %ignore webots::Robot::getGPS(const std::string &name); %ignore webots::Robot::getGyro(const std::string &name); %ignore webots::Robot::getInertialUnit(const std::string &name); %ignore webots::Robot::getJoystick(); %ignore webots::Robot::getKeyboard(); %ignore webots::Robot::getLED(const std::string &name); %ignore webots::Robot::getLidar(const std::string &name); %ignore webots::Robot::getLightSensor(const std::string &name); %ignore webots::Robot::getMotor(const std::string &name); %ignore webots::Robot::getMouse(); %ignore webots::Robot::getPen(const std::string &name); %ignore webots::Robot::getPositionSensor(const std::string &name); %ignore webots::Robot::getRadar(const std::string &name); %ignore webots::Robot::getRangeFinder(const std::string &name); %ignore webots::Robot::getReceiver(const std::string &name); %ignore webots::Robot::getSkin(const std::string &name); %ignore webots::Robot::getSpeaker(const std::string &name); %ignore webots::Robot::getTouchSensor(const std::string &name); %ignore webots::Robot::windowCustomFunction(void *arg); %ignore webots::Robot::wwiSend(const char *data, int size); %ignore webots::Robot::wwiReceive(int *size); %rename ("__internalGetDevice") webots::Robot::getDevice; %rename ("__internalGetDeviceByIndex") webots::Robot::getDeviceByIndex; %rename ("__internalGetDeviceTypeFromTag") webots::Robot::getDeviceTypeFromTag; %rename ("__internalGetDeviceNameFromTag") webots::Robot::getDeviceNameFromTag; %rename ("__internalGetDeviceTagFromIndex") webots::Robot::getDeviceTagFromIndex; %rename ("__internalGetDeviceTagFromName") webots::Robot::getDeviceTagFromName; %extend webots::Robot { %pythoncode %{ __devices = [] joystick = Joystick() keyboard = Keyboard() mouse = Mouse() import sys if sys.version_info[0] < 3: sys.stderr.write("DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of Webots will drop support for Python 2.7.\n") def createAccelerometer(self, name): return Accelerometer(name) def getAccelerometer(self, name): sys.stderr.write("DEPRECATION: Robot.getAccelerometer is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.ACCELEROMETER): return None return self.__getOrCreateDevice(tag) def createAltimeter(self, name): return Altimeter(name) def getAltimeter(self, name): sys.stderr.write("DEPRECATION: Robot.getAltimeter is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.ALTIMETER): return None return self.__getOrCreateDevice(tag) def createBrake(self, name): return Brake(name) def getBrake(self, name): sys.stderr.write("DEPRECATION: Robot.getBrake is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.BRAKE): return None return self.__getOrCreateDevice(tag) def createCamera(self, name): return Camera(name) def getCamera(self, name): sys.stderr.write("DEPRECATION: Robot.getCamera is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.CAMERA): return None return self.__getOrCreateDevice(tag) def createCompass(self, name): return Compass(name) def getCompass(self, name): sys.stderr.write("DEPRECATION: Robot.getCompass is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.COMPASS): return None return self.__getOrCreateDevice(tag) def createConnector(self, name): return Connector(name) def getConnector(self, name): sys.stderr.write("DEPRECATION: Robot.getConnector is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.CONNECTOR): return None return self.__getOrCreateDevice(tag) def createDisplay(self, name): return Display(name) def getDisplay(self, name): sys.stderr.write("DEPRECATION: Robot.getDisplay is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.DISPLAY): return None return self.__getOrCreateDevice(tag) def createDistanceSensor(self, name): return DistanceSensor(name) def getDistanceSensor(self, name): sys.stderr.write("DEPRECATION: Robot.getDistanceSensor is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.DISTANCE_SENSOR): return None return self.__getOrCreateDevice(tag) def createEmitter(self, name): return Emitter(name) def getEmitter(self, name): sys.stderr.write("DEPRECATION: Robot.getEmitter is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.EMITTER): return None return self.__getOrCreateDevice(tag) def createGPS(self, name): return GPS(name) def getGPS(self, name): sys.stderr.write("DEPRECATION: Robot.getGPS is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.GPS): return None return self.__getOrCreateDevice(tag) def createGyro(self, name): return Gyro(name) def getGyro(self, name): sys.stderr.write("DEPRECATION: Robot.getGyro is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.GYRO): return None return self.__getOrCreateDevice(tag) def createInertialUnit(self, name): return InertialUnit(name) def getInertialUnit(self, name): sys.stderr.write("DEPRECATION: Robot.getInertialUnit is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.INERTIAL_UNIT): return None return self.__getOrCreateDevice(tag) def getJoystick(self): return self.joystick def getKeyboard(self): return self.keyboard def createLED(self, name): return LED(name) def getLED(self, name): sys.stderr.write("DEPRECATION: Robot.getLED is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.LED): return None return self.__getOrCreateDevice(tag) def createLidar(self, name): return Lidar(name) def getLidar(self, name): sys.stderr.write("DEPRECATION: Robot.getLidar is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.LIDAR): return None return self.__getOrCreateDevice(tag) def createLightSensor(self, name): return LightSensor(name) def getLightSensor(self, name): sys.stderr.write("DEPRECATION: Robot.getLightSensor is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.LIGHT_SENSOR): return None return self.__getOrCreateDevice(tag) def createMotor(self, name): return Motor(name) def getMotor(self, name): sys.stderr.write("DEPRECATION: Robot.getMotor is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.LINEAR_MOTOR) and not Device.hasType(tag, Node.ROTATIONAL_MOTOR): return None return self.__getOrCreateDevice(tag) def getMouse(self): return self.mouse def createPen(self, name): return Pen(name) def getPen(self, name): sys.stderr.write("DEPRECATION: Robot.getPen is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.PEN): return None return self.__getOrCreateDevice(tag) def createPositionSensor(self, name): return PositionSensor(name) def getPositionSensor(self, name): sys.stderr.write("DEPRECATION: Robot.getPositionSensor is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.POSITION_SENSOR): return None return self.__getOrCreateDevice(tag) def createRadar(self, name): return Radar(name) def getRadar(self, name): sys.stderr.write("DEPRECATION: Robot.getRadar is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.RADAR): return None return self.__getOrCreateDevice(tag) def createRangeFinder(self, name): return RangeFinder(name) def getRangeFinder(self, name): sys.stderr.write("DEPRECATION: Robot.getRangeFinder is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.RANGE_FINDER): return None return self.__getOrCreateDevice(tag) def createReceiver(self, name): return Receiver(name) def getReceiver(self, name): sys.stderr.write("DEPRECATION: Robot.getReceiver is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.RECEIVER): return None return self.__getOrCreateDevice(tag) def createSkin(self, name): return Skin(name) def getSkin(self, name): sys.stderr.write("DEPRECATION: Robot.getSkin is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.SKIN): return None return self.__getOrCreateDevice(tag) def createSpeaker(self, name): return Speaker(name) def getSpeaker(self, name): sys.stderr.write("DEPRECATION: Robot.getSpeaker is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.SPEAKER): return None return self.__getOrCreateDevice(tag) def createTouchSensor(self, name): return TouchSensor(name) def getTouchSensor(self, name): sys.stderr.write("DEPRECATION: Robot.getTouchSensor is deprecated, please use Robot.getDevice instead.\n") tag = self.__internalGetDeviceTagFromName(name) if not Device.hasType(tag, Node.TOUCH_SENSOR): return None return self.__getOrCreateDevice(tag) def getDeviceByIndex(self, index): tag = self.__internalGetDeviceTagFromIndex(index) return self.__getOrCreateDevice(tag) def getDevice(self, name): tag = self.__internalGetDeviceTagFromName(name) return self.__getOrCreateDevice(tag) @staticmethod def internalGetDeviceFromTag(tag): if tag == 0: return None size = len(Robot.__devices) if size == 0 or tag >= size: return None return Robot.__devices[tag] def __getOrCreateDevice(self, tag): if tag == 0: return None count = self.getNumberOfDevices() size = len(Robot.__devices) # if new devices have been added, then count is greater than size # deleted devices are not removed from the C API list and don't affect the number of devices if size == count + 1 and size > 0 and tag < size: return Robot.__devices[tag] # (re-)initialize Robot.__devices list if tag > count: return None Robot.__devices = [None] * (count + 1) for i in range(0, count): otherTag = self.__internalGetDeviceTagFromIndex(i) name = self.__internalGetDeviceNameFromTag(otherTag) nodeType = self.__internalGetDeviceTypeFromTag(otherTag) if nodeType == Node.ACCELEROMETER: Robot.__devices[otherTag] = self.createAccelerometer(name) elif nodeType == Node.ALTIMETER: Robot.__devices[otherTag] = self.createAltimeter(name) elif nodeType == Node.BRAKE: Robot.__devices[otherTag] = self.createBrake(name) elif nodeType == Node.CAMERA: Robot.__devices[otherTag] = self.createCamera(name) elif nodeType == Node.COMPASS: Robot.__devices[otherTag] = self.createCompass(name) elif nodeType == Node.CONNECTOR: Robot.__devices[otherTag] = self.createConnector(name) elif nodeType == Node.DISPLAY: Robot.__devices[otherTag] = self.createDisplay(name) elif nodeType == Node.DISTANCE_SENSOR: Robot.__devices[otherTag] = self.createDistanceSensor(name) elif nodeType == Node.EMITTER: Robot.__devices[otherTag] = self.createEmitter(name) elif nodeType == Node.GPS: Robot.__devices[otherTag] = self.createGPS(name) elif nodeType == Node.GYRO: Robot.__devices[otherTag] = self.createGyro(name) elif nodeType == Node.INERTIAL_UNIT: Robot.__devices[otherTag] = self.createInertialUnit(name) elif nodeType == Node.LED: Robot.__devices[otherTag] = self.createLED(name) elif nodeType == Node.LIDAR: Robot.__devices[otherTag] = self.createLidar(name) elif nodeType == Node.LIGHT_SENSOR: Robot.__devices[otherTag] = self.createLightSensor(name) elif nodeType == Node.LINEAR_MOTOR or nodeType == Node.ROTATIONAL_MOTOR: Robot.__devices[otherTag] = self.createMotor(name) elif nodeType == Node.PEN: Robot.__devices[otherTag] = self.createPen(name) elif nodeType == Node.POSITION_SENSOR: Robot.__devices[otherTag] = self.createPositionSensor(name) elif nodeType == Node.RADAR: Robot.__devices[otherTag] = self.createRadar(name) elif nodeType == Node.RANGE_FINDER: Robot.__devices[otherTag] = self.createRangeFinder(name) elif nodeType == Node.RECEIVER: Robot.__devices[otherTag] = self.createReceiver(name) elif nodeType == Node.SPEAKER: Robot.__devices[otherTag] = self.createSpeaker(name) elif nodeType == Node.TOUCH_SENSOR: Robot.__devices[otherTag] = self.createTouchSensor(name) return Robot.__devices[tag] %} } %include //---------------------------------------------------------------------------------------------- // Supervisor //---------------------------------------------------------------------------------------------- %rename ("__internalGetFromDeviceTag") getFromDeviceTag; %include