赞
踩
新建一个控制器,命名为get_to_goal.py
Webots运行视频如下:
Webots编写控制程序使二轮差速小车导航至目标点
控制器代码如下
- from controller import Supervisor
- import math
- import random
-
- robot = Supervisor()
- # get the time step of the current world.
- timestep = int(robot.getBasicTimeStep())
-
- #获取电机
- motor_right = robot.getDevice("motorRight")
- motor_left = robot.getDevice("motorLeft")
-
- #设置电机模式与电机初始速度
- motor_right.setPosition(float("inf"))
- motor_right.setVelocity(0.0)
- motor_left.setPosition(float("inf"))
- motor_left.setVelocity(0.0)
-
-
- name = robot.getFromDef("car")
-
- # 格式化x和z,保留小数点后四位
- # robot_x = float("{:.4f}".format(x))
- # robot_z = float("{:.4f}".format(z))
- # print("X坐标:", robot_x)
- # print("Z坐标:", robot_z)
-
-
- # 假设机器人当前在原点且朝向与y轴负方向一致
- CURRENT_ANGLE = -math.pi / 2
-
- # 定义移动速度和角速度
- LINEAR_SPEED = 3.14 # 线性速度,单位:米/秒
-
- def get_to_goal(name, target_x, target_z, CURRENT_ANGLE):
- robot_x, robot_z = car_position(name)
- # 目标点与机器人之间的相对角度
- # math.atan2返回值的范围是从 -π 到 π(不包括π),表示的是 (x, y) 点与原点的连线与正x轴之间的夹角(以弧度为单位)
- target_angle = math.atan2(target_z - robot_z, target_x - robot_x)
- print("目标点与机器人之间的相对角度:", target_angle)
- angle_difference1 = target_angle - CURRENT_ANGLE
- # 到达目标点所需的角度差, 未考虑angle_difference1=NaN
- if angle_difference1 > math.pi:
- angle_difference = angle_difference1 - 2 * math.pi
- print("到达目标点所需的角度差:", angle_difference)
- else:
- angle_difference = angle_difference1
- print("到达目标点所需的角度差:", angle_difference)
- rotate_to_target_angle(name, -angle_difference) # 仿真方向与正常方向相反
- move_to_target(name, target_x, target_z)
-
-
- def car_angle(name):
- rotation = name.getField("rotation")
- WorldRot = rotation.getSFRotation()
- qx, qy, qz, qw = WorldRot
- # theta = 2 * math.acos(qw)
- return qw
- def car_position(name):
- trans = name.getField("translation")
- WorldCoord = trans.getSFVec3f()
- x, _, z = WorldCoord
- return x, z
-
- # 首先旋转到目标角度
- def rotate_to_target_angle(name, target_angle):
- # 对应仿真左转
- if target_angle - car_angle(name) > 0:
- motor_left.setVelocity(LINEAR_SPEED/8)
- motor_right.setVelocity(-LINEAR_SPEED/8)
- while robot.step(timestep) != -1:
- if car_angle(name) >= target_angle:
- motor_left.setVelocity(0.)
- motor_right.setVelocity(0.)
- return
- # 对应仿真右转 car_angle为负
- if target_angle - car_angle(name) < 0:
- motor_left.setVelocity(-LINEAR_SPEED/8)
- motor_right.setVelocity(LINEAR_SPEED/8)
- while robot.step(timestep) != -1:
- # print("car_angle" + str(car_angle(name)))
- if car_angle(name) <= target_angle:
- print("car_angle" + str(car_angle(name)))
- print("target_angle" + str(target_angle))
- motor_left.setVelocity(0.)
- motor_right.setVelocity(0.)
- return
-
- # 旋转到目标角度后,直线移动到目标点
- def move_to_target(name, TARGET_X, TARGET_Y):
- left_speed = LINEAR_SPEED
- right_speed = LINEAR_SPEED
-
- # 负号对应仿真前进直线移动
- motor_left.setVelocity(-left_speed)
- motor_right.setVelocity(-right_speed)
- while robot.step(timestep) != -1:
- x, z = car_position(name)
- dis = math.sqrt((TARGET_X - x) ** 2 + (TARGET_Y - z) ** 2)
- # print("dis:", dis)
- if dis <= 0.01:
- print("x:" + str(x))
- print("z:" + str(z))
- motor_left.setVelocity(0)
- motor_right.setVelocity(0)
- return
- while True:
- x = random.uniform(0, 0.4)
- y = random.uniform(0, 0.4)
- print("x:" + str(x))
- print("y:" + str(y))
- get_to_goal(name,x, y, CURRENT_ANGLE)
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。