webots notes the next day
1. Use of actuator
- The actuator is also similar to the sensor, and the label used is Wb_Device_Tag, the calling function is also wb_robot_get_device(), but there is no need to call the open function wb_*_enable().
- For motion control, the action is divided into several steps for control.
wb_motor_set_position() gives the corresponding position request to the motor.
#include <webots/robot.h> #include <webots/motor.h> #include <math.h> #define TIME_STEP 32 int main() { wb_robot_init(); WbDeviceTag motor = wb_robot_get_device("my_motor"); double F = 2.0; // frequency 2 Hz double t = 0.0; // elapsed simulation time while (1) { double pos = sin(t * 2.0 * M_PI * F); wb_motor_set_position(motor, pos); wb_robot_step(TIME_STEP); t += (double)TIME_STEP / 1000.0; } return 0; }
- webots/motor.h has the definition of motor speed, acceleration, force and various parameters.
- wb_motor_set_position() only specifies the expected target value. Similar to the actual robot, the rotation angle of the motor can not reach the expected value because the torque of the motor is not enough to resist gravity. If you want to control the rotation angle of multiple motors at the same time, you need to set the expected value for the rotation angle of each motor.
2. wb_ robot_ Use of step()
Webots are used in two different times: control delay and analog delay.
- Control delay (use of wb_robot_step())
- Simulation delay (definition in scene tree: WorldInfo.basicTimeStep)
Each controller needs to call wb_robot_step(), otherwise the sensor and actuator will not update data and get stuck (only in synchronous mode)
3. Use with sensor
Webots and each robot controller run in an individual process. For example, the simulation includes connecting robots. There are three processes in total: one is webots and the other two are robots. Each controller procedure calls wb_robot_step() to exchange sensor and actuator data. For example, wb_motor_set_position also cannot send data to webots immediately.
See the following code:
while(1){ double d1 = wb_distance_sensor_get_value(ds1); double d2 = wb_distance_sensor_get_value(ds2); if(d2<d1) //WRONG: d2 will always equal to d1 here avoidCollision(); wb_robot_step(40); }
Because there is no WB between the two sensor data reading functions_ robot_ Step() function, so two values cannot be changed at the same time.
This is the correct code:
while(1){ double d1 = wb_distance_sensor_get_value(ds1); wb_robot_step(); double d2 = wb_distance_sensor_get_value(ds2); if (d2<d1) avoidCollision(); wb_robot_step(); }
However, it is generally recommended to include only one | WB in the main control cycle_ robot_ Step() function to update all sensor and actuator data at the same time. As follows:
while(1){ readSensors(); actuateMotors(); wb_robot_step(TIME_STEP); }
You can put WB here_ robot_ The step () function is placed at the beginning of the loop. This allows the sensor to have valid data before reading the sensor data. Otherwise, the sensor may be undefined for the first iteration.
while(1){ wb_robot_step(TIME_STEP); readSensors(); actuateMotors(); }
example:
#include <webots/robot.h> #include <webots/differential_wheels.h> #include <webots/distance_sensor.h> #define TIME_STEP 32 int main() { wb_robot_init(); WbDeviceTag left_sensor = wb_robot_get_device("left_sensor"); WbDeviceTag right_sensor = wb_robot_get_device("right_sensor"); wb_distance_sensor_enable(left_sensor, TIME_STEP); wb_distance_sensor_enable(right_sensor, TIME_STEP); while (1) { wb_robot_step(TIME_STEP); // read sensors double left_dist = wb_distance_sensor_get_value(left_sensor); double right_dist = wb_distance_sensor_get_value(right_sensor); // compute behavior double left = compute_left_speed(left_dist, right_dist); double right = compute_right_speed(left_dist, right_dist); // actuate wheel motors wb_differential_wheels_set_speed(left, right); } return 0; }