Webots Reference Manual - chapter 3 - section 40

Webots Reference Manual


3.40 Receiver

Derived from Device.

Receiver {
  SFString  type        "radio"    # or "serial" or "infra-red"
  SFFloat   aperture    -1         # -1 or [0,2pi]
  SFInt32   channel     0          # [-1,inf)
  SFInt32   baudRate    -1         # -1 or [0,inf)
  SFInt32   byteSize    8          # [8,inf)
  SFInt32   bufferSize  4096       # [1,inf)
}

3.40.1 Description

The Receiver node is used to model radio, serial or infra-red receivers. A Receiver node must be added to the children of a robot or supervisor. Please note that a Receiver can receive data but it cannot send it. In order to achieve bidirectional communication, a robot needs to have both an Emitter and a Receiver on board.

3.40.2 Field Summary

3.40.3 Receiver Functions



NAME

   wb_receiver_enable, wb_receiver_disable, wb_receiver_get_sampling_period - enable and disable receiver

SYNOPSIS [C++] [Java] [Python] [Matlab]

  #include <webots/receiver.h>

  void wb_receiver_enable(WbDeviceTag tag, int ms);
  void wb_receiver_disable(WbDeviceTag tag);
  int wb_receiver_get_sampling_period(WbDeviceTag tag);

DESCRIPTION

wb_receiver_enable() starts the receiver listening for incoming data packets. Data reception is activated in the background of the controller's loop at a rate of once every ms milliseconds. Incoming data packet are appended to the tail of the reception queue (see figure 3.23). Incoming data packets will be discarded if the receiver's buffer size (specified in the Receiver node) is exceeded. To avoid buffer overflow, the data packets should be read at a high enough rate by the controller program. The function wb_receiver_disable() stops the background listening.

The wb_receiver_get_sampling_period() function returns the period given into the wb_receiver_enable() function, or 0 if the device is disabled.



NAME

   wb_receiver_get_queue_length, wb_receiver_next_packet - check for the presence of data packets in the receivers queue

SYNOPSIS [C++] [Java] [Python] [Matlab]

  #include <webots/receiver.h>

  int wb_receiver_get_queue_length(WbDeviceTag tag);
  void wb_receiver_next_packet(WbDeviceTag tag);

DESCRIPTION

The wb_receiver_get_queue_length() function returns the number of data packets currently present in the receiver's queue (see figure 3.23).

The wb_receiver_next_packet() function deletes the head packet. The next packet in the queue, if any, becomes the new head packet. The user must copy useful data from the head packet, before calling wb_receiver_next_packet(). It is illegal to call wb_receiver_next_packet() when the queue is empty (wb_receiver_get_queue_length() == 0). Here is a usage example:

language: C

while (wb_receiver_get_queue_length(tag) > 0) {
  const char *message = wb_receiver_get_data(tag);
  const double *dir = wb_receiver_get_emitter_direction(tag);
  double signal = wb_receiver_get_signal_strength(tag);
  printf("received: %s (signal=%g, dir=[%g %g %g])\n",
         message, signal, dir[0], dir[1], dir[2]);
  wb_receiver_next_packet(tag);
}

This example assumes that the data (message) was sent in the form of a null-terminated string. The Emitter/Receiver API does not put any restriction on the type of data that can be transmitted. Any user chosen format is suitable, as long as emitters and receivers agree.

receiver_queue_figure

Figure 3.23: Receiver's packet queue

Webots' Emitter/Receiver API guarantees that:

However, the Emitter/Receiver API does not guarantee a specific schedule for the transmission. Sometimes several packets may be bundled and received together. For example, imagine a simple setup where two robots have an Emitter and a Receiver on board. If both robots use the same controller time step and each one sends a packet at every time step, then the Receivers will receive, on average, one data packet at each step, but they may sometimes get zero packets, and sometimes two! Therefore it is recommend to write code that is tolerant to variations in the transmission timing and that can deal with the eventuality of receiving several or no packets at all during a particular time step. The wb_receiver_get_queue_length() function should be used to check how many packets are actually present in the Receiver's queue. Making assumptions based on timing will result in code that is not robust.



NAME

   wb_receiver_get_data, wb_receiver_get_data_size - get data and size of the current packet

SYNOPSIS [C++] [Java] [Python] [Matlab]

  #include <webots/receiver.h>

  const void *wb_receiver_get_data(WbDeviceTag tag);
  int wb_receiver_get_data_size(WbDeviceTag tag);

DESCRIPTION

The wb_receiver_get_data() function returns the data of the packet at the head of the reception queue (see figure 3.23). The returned data pointer is only valid until the next call to the function wb_receiver_next_packet(). It is illegal to call wb_receiver_get_data() when the queue is empty (wb_receiver_get_queue_length() == 0). The Receiver node knows nothing about that structure of the data being sent but its byte size. The emitting and receiving code is responsible to agree on a specific format.

The wb_receiver_get_data_size() function returns the number of data bytes present in the head packet of the reception queue. The data size is always equal to the size argument of the corresponding emitter_send_packet() call. It is illegal to call wb_receiver_get_data_size() when the queue is empty (wb_receiver_get_queue_length() == 0).

language: Python
The getData() function returns a string. Similarly to the sendPacket() function of the Emitter device, using the functions of the struct module is recommended for sending primitive data types. Here is an example for getting the data:

import struct
#...
message=receiver.getData()
dataList=struct.unpack("chd",message)

language: Matlab
The Matlab wb_receiver_get_data() function returns a MATLAB libpointer. The receiving code is responsible for extracting the data from the libpointer using MATLAB's setdatatype() and get() functions. Here is an example on how to send and receive a 2x3 MATLAB matrix.

% sending robot
emitter = wb_robot_get_device('emitter');

A = [1, 2, 3; 4, 5, 6];
wb_emitter_send(emitter, A);

% receiving robot
receiver = wb_robot_get_device('receiver');
wb_receiver_enable(receiver, TIME_STEP);

while wb_receiver_get_queue_length(receiver) > 0
  pointer = wb_receiver_get_data(receiver);
  setdatatype(pointer, 'doublePtr', 2, 3);
  A = get(pointer, 'Value');
  wb_receiver_next_packet(receiver);
end

The MATLAB wb_receiver_get_data() function can also take a second argument that specifies the type of the expected data. In this case the function does not return a libpointer but an object of the specified type, and it is not necessary to call setdatatype() and get(). For example wb_receiver_get_data() can be used like this:

% receiving robot
receiver = wb_robot_get_device('receiver');
wb_receiver_enable(receiver, TIME_STEP);

while wb_receiver_get_queue_length(receiver) > 0
  A = wb_receiver_get_data(receiver, 'double');
  wb_receiver_next_packet(receiver);
end

The available types are 'uint8', 'double' and 'string'. More sophisticated data typed must be accessed explicitly using setdatatype() and get().


NAME

   wb_receiver_get_signal_strength, wb_receiver_get_emitter_direction - get signal strength and emitter direction

SYNOPSIS [C++] [Java] [Python] [Matlab]

  #include <webots/receiver.h>

  double wb_receiver_get_signal_strength(WbDeviceTag tag);
  const double *wb_receiver_get_emitter_direction(WbDeviceTag tag);

DESCRIPTION

The wb_receiver_get_signal_strength() function operates on the head packet in the receiver's queue (see figure 3.23). It returns the simulated signal strength at the time the packet was transmitted. This signal strength is equal to the inverse of the distance between the emitter and the receiver squared. In other words, s = 1 / r2, where s is the signal strength and r is the distance between emitter and receiver. It is illegal to call this function if the receiver's queue is empty (wb_receiver_get_queue_length() == 0).

The function wb_receiver_get_emitter_direction() also operates on the head packet in the receiver's queue. It returns a normalized (length=1) vector that indicates the direction of the emitter with respect to the receiver's coordinate system. The three vector components indicate the x, y , and z-directions of the emitter, respectively. For example, if the emitter was exactly in front of the receiver, then the vector would be [0 0 1]. In the usual orientation used for 2D simulations (robots moving in the xz-plane and the y -axis oriented upwards), a positive x -component indicates that the emitter is located to the left of the receiver while a negative x -component indicates that the emitter is located to the right. The returned vector is valid only until the next call to wb_receiver_next_packet(). It is illegal to call this function if the receiver's queue is empty (wb_receiver_get_queue_length() == 0).

language: Python
getEmitterDirection() returns the vector as a list containing three floats.


NAME

   wb_receiver_set_channel, wb_receiver_get_channel - set and get the receiver's channel.

SYNOPSIS [C++] [Java] [Python] [Matlab]

  #include <webots/receiver.h>

  void wb_receiver_set_channel(WbDeviceTag tag, int channel);
  int wb_receiver_get_channel(WbDeviceTag tag);

DESCRIPTION

The wb_receiver_set_channel() function allows a receiver to change its reception channel. It modifies the channel field of the corresponding Receiver node. Normally, a receiver can only receive data packets from emitters that use the same channel. However, the special WB_CHANNEL_BROADCAST value can be used to listen simultaneously to all channels.

The wb_receiver_get_channel() function returns the current channel number of the receiver.

language: C++, Java, Python
In the oriented-object APIs, the WB_CHANNEL_BROADCAST constant is available as static integer of the Receiver class (Receiver::CHANNEL_BROADCAST).
release 7.0.2
Copyright © 2012 Cyberbotics Ltd. All right reserved.