Webots 的官网有比较详细的API 介绍,可以参考:
Webots API (用到的函数这里都有)
Webots 官网指导 (有教程)
然后软件里也有各种例子,可以参考。
附上一个之前写过的代码,供参考。(但Webots的版本升级后,函数有些可能会不同,仅供参考。)
#include <webots/robot.h> #include <webots/supervisor.h> #include <webots/gyro.h> #include <webots/motor.h> #include <stdio.h> #include <math.h> #include <webots/position_sensor.h> #include <webots/accelerometer.h> #define PI 3.1415926539 #define TIME_STEP 10 //in ms #define INF 9999999.0 #define GRAVITY 9.81 //in m s-2 #define MASS 90 //in kg #define THIGH_LENGTH 0.35 //in metres #define SHIN_LENGTH 0.35 //in metres #define HALF_BWIDTH 0.25 //in metres #define HALF_BLENGTH 0.5 //in metres //METHOD 1: TILT BALANCE WALK: walk/run faster by reducing front hip angle and increase frequency. int main(int argc, char **argv) { wb_robot_init(); WbDeviceTag hip[4], hiproll[4], knee[4], gyro, accel; WbDeviceTag hip_sensor[4],hiproll_sensor[4],knee_sensor[4]; FILE *OUT,*MOTOR; OUT=fopen("C:/Users/think/Desktop/my_project/controllers/flight/OUT.txt","w"); MOTOR=fopen("C:/Users/think/Desktop/my_project/controllers/flight/MOTOR.txt","w"); int timestep = 0,cumul_time = 0, i, phase=0; const double *gyro_values, *accel_values; double com_roll=0, com_pitch=0, com_yaw=0, x_velocity=0, global_x_accel, z_height; double ref_xvel; double left_height, right_height; double hip_angle[4], hiproll_angle[4], knee_angle[4], ankle_angle[4], ankleroll_angle[4]; double frequency,air_time,sweep_angle,forward_sweep_ratio; double hip_force,hiproll_force,knee_force; int cycle = 1; //define reference values / Characteristics of gait //Independent Variables frequency = 2.2; sweep_angle = 0.05*PI; forward_sweep_ratio = 0; //Dependent Variables air_time = 200/frequency; // in ms ref_xvel = 0.1; //Index of joints: // 0 - Left Front // 1 - Right Front // 2 - Left Back // 3 - Right Back //Assign Wb id tags to actuators hip[0] = wb_robot_get_device("LF_hip"); hiproll[0] = wb_robot_get_device("LF_hiproll"); knee[0] = wb_robot_get_device("LF_knee"); hip[1] = wb_robot_get_device("RF_hip"); hiproll[1] = wb_robot_get_device("RF_hiproll"); knee[1] = wb_robot_get_device("RF_knee"); hip[2] = wb_robot_get_device("LB_hip"); hiproll[2] = wb_robot_get_device("LB_hiproll"); knee[2] = wb_robot_get_device("LB_knee"); hip[3] = wb_robot_get_device("RB_hip"); hiproll[3] = wb_robot_get_device("RB_hiproll"); knee[3] = wb_robot_get_device("RB_knee"); //Assign Wb id tags to actuators sensors hip_sensor[0]=wb_robot_get_device("LF_hip_sensor"); hiproll_sensor[0]=wb_robot_get_device("LF_hiproll_sensor"); knee_sensor[0]=wb_robot_get_device("LF_knee_sensor"); hip_sensor[1]=wb_robot_get_device("RF_hip_sensor"); hiproll_sensor[1]=wb_robot_get_device("RF_hiproll_sensor"); knee_sensor[1]=wb_robot_get_device("RF_knee_sensor"); hip_sensor[2]=wb_robot_get_device("LB_hip_sensor"); hiproll_sensor[2]=wb_robot_get_device("LB_hiproll_sensor"); knee_sensor[2]=wb_robot_get_device("LB_knee_sensor"); hip_sensor[3]=wb_robot_get_device("RB_hip_sensor"); hiproll_sensor[3]=wb_robot_get_device("RB_hiproll_sensor"); knee_sensor[3]=wb_robot_get_device("RB_knee_sensor"); //Enable position detection of motors and force detection for(i=0;i<=3;i++){ wb_position_sensor_enable(hip_sensor[i],TIME_STEP); wb_position_sensor_enable(hiproll_sensor[i],TIME_STEP); wb_position_sensor_enable(knee_sensor[i],TIME_STEP); wb_motor_enable_force_feedback(hip[i],TIME_STEP); wb_motor_enable_force_feedback(hiproll[i],TIME_STEP); wb_motor_enable_force_feedback(knee[i],TIME_STEP); } //Assign Wb id tags to gyroscope&accelerometer and enable them gyro = wb_robot_get_device("gyroscope"); accel = wb_robot_get_device("accelerometer"); wb_gyro_enable(gyro,TIME_STEP); wb_accelerometer_enable(accel,TIME_STEP); while (wb_robot_step(TIME_STEP) != -1) { //Calculate angular positions using gyroscope **ASSUME ROBOT STARTS IN PERFECT ORIENTATION** gyro_values = wb_gyro_get_values(gyro); com_roll += gyro_values[0]*0.001*TIME_STEP; // x axis com_pitch += (-gyro_values[2])*0.001*TIME_STEP; // y axis //com_pitch += (gyro_values[1])*0.001*TIME_STEP; // y axis com_yaw += gyro_values[1]*0.001*TIME_STEP; // z axis //fprintf(OUT,"%f %f %f\n",com_pitch,com_roll,com_yaw); //fprintf(OUT,"%f %f %f\n",com_pitch,com_roll,com_yaw); //Get all actuated joint positions for(i=0;i<=3;i++){ hip_angle[i]=wb_position_sensor_get_value(hip_sensor[i]); hiproll_angle[i]=wb_position_sensor_get_value(hiproll_sensor[i]); knee_angle[i]=wb_position_sensor_get_value(knee_sensor[i]); //fprintf(OUT,"%d ) %f %f %f\n",i,hip_angle[i],hiproll_angle[i],knee_angle[i]); } //Calculate ankle DoF positions for(i=0;i<=3;i++){ ankle_angle[i] = -com_pitch - hip_angle[i] - knee_angle[i]; ankleroll_angle[i] = -com_roll - hiproll_angle[i]; //fprintf(OUT,"%d ) %f %f\n",i,ankle_angle[i],ankleroll_angle[i]); } //Phase alternation (0 - In air, 1 - RF&LB, 2 - In air, 3 - LF&RB) switch(phase){ case 0: if(timestep >= air_time) phase = 1; break; case 1: if(timestep >= (0.5/frequency)*1000){ phase = 2; timestep = 0; } break; case 2: if(timestep >= air_time) phase = 3; break; case 3: if(timestep >= (0.5/frequency)*1000){ phase = 0; timestep = 0; //fprintf(OUT,"\nNEW CYCLE\n"); //fprintf(MOTOR,"\nNEW CYCLE\n"); cycle++; } break; default: break; } //Update x_velocity accel_values = wb_accelerometer_get_values(accel); global_x_accel= ( accel_values[0] - GRAVITY*sin(com_pitch) ) / (cos(com_pitch)); x_velocity += global_x_accel*0.001*TIME_STEP; if(cycle == 5) fprintf(OUT,"%f\n",x_velocity); //Calculate z_height of body CoM (Which pair of legs to use depends on phase) if(phase == 1){ left_height = SHIN_LENGTH*cos(ankle_angle[2]) + THIGH_LENGTH*cos(ankle_angle[2] + knee_angle[2]); right_height = SHIN_LENGTH*cos(ankle_angle[1]) + THIGH_LENGTH*cos(ankle_angle[1] + knee_angle[1]); z_height = 0.5*( right_height*cos(ankleroll_angle[1]) + left_height*cos(ankleroll_angle[2]) ); }else if(phase == 3){ left_height = SHIN_LENGTH*cos(ankle_angle[0]) + THIGH_LENGTH*cos(ankle_angle[0] + knee_angle[0]); right_height = SHIN_LENGTH*cos(ankle_angle[3]) + THIGH_LENGTH*cos(ankle_angle[3] + knee_angle[3]); z_height = 0.5*( right_height*cos(ankleroll_angle[3]) + left_height*cos(ankleroll_angle[0]) ); } //fprintf(OUT,"%f\n",z_height); //Actuations //Hop on the spot for 2 periods if(cumul_time <= (2/frequency)*1000){ if(phase == 0 || phase == 1){ wb_motor_set_position(hip[0],-3*PI/8); wb_motor_set_position(hip[1],-PI/8); wb_motor_set_position(hip[2],PI/8); wb_motor_set_position(hip[3],3*PI/8); wb_motor_set_position(knee[0],3*PI/4); wb_motor_set_position(knee[1],PI/4); wb_motor_set_position(knee[2],-PI/4); wb_motor_set_position(knee[3],-3*PI/4); wb_motor_set_position(hiproll[0],0); wb_motor_set_position(hiproll[1],0); wb_motor_set_position(hiproll[2],0); wb_motor_set_position(hiproll[3],0); wb_motor_set_control_pid(hip[0],10,0,0); wb_motor_set_control_pid(hip[1],10,0,0); wb_motor_set_control_pid(hip[2],10,0,0); wb_motor_set_control_pid(hip[3],10,0,0); wb_motor_set_control_pid(knee[0],10,0,0); wb_motor_set_control_pid(knee[1],10,0,0); wb_motor_set_control_pid(knee[2],10,0,0); wb_motor_set_control_pid(knee[3],10,0,0); wb_motor_set_control_pid(hiproll[0],10,0,0); wb_motor_set_control_pid(hiproll[1],10,0,0); wb_motor_set_control_pid(hiproll[2],10,0,0); wb_motor_set_control_pid(hiproll[3],10,0,0); }else if(phase == 2 || phase == 3){ wb_motor_set_position(hip[0],-PI/8); wb_motor_set_position(hip[1],-3*PI/8); wb_motor_set_position(hip[2],3*PI/8); wb_motor_set_position(hip[3],PI/8); wb_motor_set_position(knee[0],PI/4); wb_motor_set_position(knee[1],3*PI/4); wb_motor_set_position(knee[2],-3*PI/4); wb_motor_set_position(knee[3],-PI/4); wb_motor_set_position(hiproll[0],0); wb_motor_set_position(hiproll[1],0); wb_motor_set_position(hiproll[2],0); wb_motor_set_position(hiproll[3],0); wb_motor_set_control_pid(hip[0],10,0,0); wb_motor_set_control_pid(hip[1],10,0,0); wb_motor_set_control_pid(hip[2],10,0,0); wb_motor_set_control_pid(hip[3],10,0,0); wb_motor_set_control_pid(knee[0],10,0,0); wb_motor_set_control_pid(knee[1],10,0,0); wb_motor_set_control_pid(knee[2],10,0,0); wb_motor_set_control_pid(knee[3],10,0,0); wb_motor_set_control_pid(hiproll[0],10,0,0); wb_motor_set_control_pid(hiproll[1],10,0,0); wb_motor_set_control_pid(hiproll[2],10,0,0); wb_motor_set_control_pid(hiproll[3],10,0,0); } cumul_time += 10; }else{ //Duty Movement positions if(phase == 0){ wb_motor_set_position(hip[0],-3*PI/8); wb_motor_set_position(hip[1],-PI/8+forward_sweep_ratio*sweep_angle); wb_motor_set_position(hip[2],PI/8+forward_sweep_ratio*sweep_angle); wb_motor_set_position(hip[3],3*PI/8); wb_motor_set_position(knee[0],3*PI/4); wb_motor_set_position(knee[1],PI/4); wb_motor_set_position(knee[2],-PI/4); wb_motor_set_position(knee[3],-3*PI/4); wb_motor_set_position(hiproll[0],0); wb_motor_set_position(hiproll[1],0); wb_motor_set_position(hiproll[2],0); wb_motor_set_position(hiproll[3],0); wb_motor_set_control_pid(hip[0],10,0,0); wb_motor_set_control_pid(hip[1],10,0,0); wb_motor_set_control_pid(hip[2],10,0,0); wb_motor_set_control_pid(hip[3],10,0,0); wb_motor_set_control_pid(knee[0],10,0,0); wb_motor_set_control_pid(knee[1],10,0,0); wb_motor_set_control_pid(knee[2],10,0,0); wb_motor_set_control_pid(knee[3],10,0,0); wb_motor_set_control_pid(hiproll[0],10,0,0); wb_motor_set_control_pid(hiproll[1],10,0,0); wb_motor_set_control_pid(hiproll[2],10,0,0); wb_motor_set_control_pid(hiproll[3],10,0,0); }else if(phase == 1){ wb_motor_set_position(hip[0],-3*PI/8); wb_motor_set_position(hip[1],-PI/8-(1-forward_sweep_ratio)*sweep_angle); wb_motor_set_position(hip[2],PI/8-(1-forward_sweep_ratio)*sweep_angle); wb_motor_set_position(hip[3],3*PI/8); wb_motor_set_position(knee[0],3*PI/4); wb_motor_set_position(knee[1],PI/4); wb_motor_set_position(knee[2],-PI/4); wb_motor_set_position(knee[3],-3*PI/4); wb_motor_set_position(hiproll[0],0); wb_motor_set_position(hiproll[1],0); wb_motor_set_position(hiproll[2],0); wb_motor_set_position(hiproll[3],0); wb_motor_set_control_pid(hip[0],10,0,0); wb_motor_set_control_pid(hip[1],10,0,0); wb_motor_set_control_pid(hip[2],10,0,0); wb_motor_set_control_pid(hip[3],10,0,0); wb_motor_set_control_pid(knee[0],10,0,0); wb_motor_set_control_pid(knee[1],10,0,0); wb_motor_set_control_pid(knee[2],10,0,0); wb_motor_set_control_pid(knee[3],10,0,0); wb_motor_set_control_pid(hiproll[0],10,0,0); wb_motor_set_control_pid(hiproll[1],10,0,0); wb_motor_set_control_pid(hiproll[2],10,0,0); wb_motor_set_control_pid(hiproll[3],10,0,0); }else if(phase == 2){ wb_motor_set_position(hip[0],-PI/8+forward_sweep_ratio*sweep_angle); wb_motor_set_position(hip[1],-3*PI/8); wb_motor_set_position(hip[2],3*PI/8); wb_motor_set_position(hip[3],PI/8+forward_sweep_ratio*sweep_angle); wb_motor_set_position(knee[0],PI/4); wb_motor_set_position(knee[1],3*PI/4); wb_motor_set_position(knee[2],-3*PI/4); wb_motor_set_position(knee[3],-PI/4); wb_motor_set_position(hiproll[0],0); wb_motor_set_position(hiproll[1],0); wb_motor_set_position(hiproll[2],0); wb_motor_set_position(hiproll[3],0); wb_motor_set_control_pid(hip[0],10,0,0); wb_motor_set_control_pid(hip[1],10,0,0); wb_motor_set_control_pid(hip[2],10,0,0); wb_motor_set_control_pid(hip[3],10,0,0); wb_motor_set_control_pid(knee[0],10,0,0); wb_motor_set_control_pid(knee[1],10,0,0); wb_motor_set_control_pid(knee[2],10,0,0); wb_motor_set_control_pid(knee[3],10,0,0); wb_motor_set_control_pid(hiproll[0],10,0,0); wb_motor_set_control_pid(hiproll[1],10,0,0); wb_motor_set_control_pid(hiproll[2],10,0,0); wb_motor_set_control_pid(hiproll[3],10,0,0); }else if(phase == 3){ wb_motor_set_position(hip[0],-PI/8-(1-forward_sweep_ratio)*sweep_angle); wb_motor_set_position(hip[1],-3*PI/8); wb_motor_set_position(hip[2],3*PI/8); wb_motor_set_position(hip[3],PI/8-(1-forward_sweep_ratio)*sweep_angle); wb_motor_set_position(knee[0],PI/4); wb_motor_set_position(knee[1],3*PI/4); wb_motor_set_position(knee[2],-3*PI/4); wb_motor_set_position(knee[3],-PI/4); wb_motor_set_position(hiproll[0],0); wb_motor_set_position(hiproll[1],0); wb_motor_set_position(hiproll[2],0); wb_motor_set_position(hiproll[3],0); wb_motor_set_control_pid(hip[0],10,0,0); wb_motor_set_control_pid(hip[1],10,0,0); wb_motor_set_control_pid(hip[2],10,0,0); wb_motor_set_control_pid(hip[3],10,0,0); wb_motor_set_control_pid(knee[0],10,0,0); wb_motor_set_control_pid(knee[1],10,0,0); wb_motor_set_control_pid(knee[2],10,0,0); wb_motor_set_control_pid(knee[3],10,0,0); wb_motor_set_control_pid(hiproll[0],10,0,0); wb_motor_set_control_pid(hiproll[1],10,0,0); wb_motor_set_control_pid(hiproll[2],10,0,0); wb_motor_set_control_pid(hiproll[3],10,0,0); } } //Get Motor force info if(cycle == 5){ for(i=0;i<=3;i++){ hip_force = wb_servo_get_motor_force_feedback(hip[i]); hiproll_force = wb_servo_get_motor_force_feedback(hiproll[i]); knee_force = wb_servo_get_motor_force_feedback(knee[i]); fprintf(MOTOR,"%f\t%f\t%f\t",hip_force,hiproll_force,knee_force); } fprintf(MOTOR,"\n"); } timestep +=10; } fclose(OUT); fclose(MOTOR); wb_robot_cleanup(); return 0; }
如果有其他更多教程,会补充。