carla软件人工控制车辆的python代码问题

希望能够帮我分析一下如下代码为什么不能对生成的车辆进行人工控制,如果可以的话请帮我改进一下,使其能对生成的车辆进行人工控制

 # -*- coding: utf-8 -*
#!/usr/bin/env python
"""

"""
import glob
import os
import sys
import time

try:
    sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
        sys.version_info.major,
        sys.version_info.minor,
        'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
    pass

import carla
import random
import numpy as np
import cv2
from queue import Queue, Empty
import copy
import random
import pygame
random.seed(0)

# args
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--host', metavar='H',    default='127.0.0.1', help='IP of the host server (default: 127.0.0.1)')
parser.add_argument('--port', '-p',           default=2000, type=int, help='TCP port to listen to (default: 2000)')
parser.add_argument('--tm_port',              default=8000, type=int, help='Traffic Manager Port (default: 8000)')
parser.add_argument('--ego-spawn', type=list, default=None, help='[x,y] in world coordinate')
parser.add_argument('--top-view',             default=True, help='Setting spectator to top view on ego car')
parser.add_argument('--map',                  default='Town04', help='Town Map')
parser.add_argument('--sync',                 default=True, help='Synchronous mode execution')
parser.add_argument('--sensor-h',             default=2.4, help='Sensor Height')
# 给绝对路径 记得改位置哦!
parser.add_argument('--save-path',            default='/home/ubuntu/makabaka/data/', help='Synchronous mode execution')
args = parser.parse_args()

# 图片大小可自行修改
IM_WIDTH = 256
IM_HEIGHT = 256


actor_list, sensor_list = [], []
sensor_type = ['rgb','lidar','imu','gnss']
def main(args):
    # We start creating the client
    client = carla.Client(args.host, args.port)
    client.set_timeout(5.0)
    
    # world = client.get_world()
    world = client.load_world('Town01')
    blueprint_library = world.get_blueprint_library()
    try:
        original_settings = world.get_settings()
        settings = world.get_settings()

        # We set CARLA syncronous mode
        settings.fixed_delta_seconds = 0.05
        settings.synchronous_mode = True
        world.apply_settings(settings)
        spectator = world.get_spectator()

        # 手动规定
        # transform_vehicle = carla.Transform(carla.Location(0, 10, 0), carla.Rotation(0, 0, 0))
        # 自动选择
        transform_vehicle = random.choice(world.get_map().get_spawn_points())
        ego_vehicle = world.spawn_actor(random.choice(blueprint_library.filter("model3")), transform_vehicle)
        actor_list.append(ego_vehicle)

        def __init__(self):
            # Conrol parameters to store the control state
            self._vehicle = ego_vehicle
            self._steer = 0
            self._throttle = False
            self._brake = False
            self._steer = None
            self._steer_cache = 0
            # A carla.VehicleControl object is needed to alter the 
            # vehicle's control state
            self._control = carla.VehicleControl()

            # Check for key press events in the PyGame window
            # and define the control state
            def parse_control(self, event):
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_RETURN:
                        self._ego_vehicle.set_autopilot(False)
                    if event.key == pygame.K_UP:
                        self._throttle = True
                    if event.key == pygame.K_DOWN:
                        self._brake = True
                    if event.key == pygame.K_RIGHT:
                        self._steer = 1
                    if event.key == pygame.K_LEFT:
                        self._steer = -1
                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_UP:
                        self._throttle = False
                    if event.key == pygame.K_DOWN:
                        self._brake = False
                        self._control.reverse = False
                    if event.key == pygame.K_RIGHT:
                        self._steer = None
                    if event.key == pygame.K_LEFT:
                        self._steer = None
    
            # Process the current control state, change the control parameter
            # if the key remains pressed
            def process_control(self):
            
                if self._throttle: 
                   self._control.throttle = min(self._control.throttle + 0.01, 1)
                   self._control.gear = 1
                   self._control.brake = False
                elif not self._brake:
                   self._control.throttle = 0.0
            
                if self._brake:
                    # If the down arrow is held down when the car is stationary, switch to reverse
                    if self._ego_vehicle.get_velocity().length() < 0.01 and not self._control.reverse:
                        self._control.brake = 0.0
                        self._control.gear = 1
                        self._control.reverse = True
                        self._control.throttle = min(self._control.throttle + 0.1, 1)
                    elif self._control.reverse:
                        self._control.throttle = min(self._control.throttle + 0.1, 1)
                    else:
                        self._control.throttle = 0.0
                        self._control.brake = min(self._control.brake + 0.3, 1)
                else:
                    self._control.brake = 0.0
            
                if self._steer is not None:
                    if self._steer == 1:
                       self._steer_cache += 0.03
                    if self._steer == -1:
                       self._steer_cache -= 0.03
                    min(0.7, max(-0.7, self._steer_cache))
                    self._control.steer = round(self._steer_cache,1)
                else:
                    if self._steer_cache > 0.0:
                       self._steer_cache *= 0.2
                    if self._steer_cache < 0.0:
                       self._steer_cache *= 0.2
                       if 0.01 > self._steer_cache > -0.01:
                           self._steer_cache = 0.0
                       self._control.steer = round(self._steer_cache,1)
    
                # Ápply the control parameters to the ego vehicle
                self._vehicle.apply_control(self._control)

        #-------------------------- 进入传感器部分 --------------------------#
        sensor_queue = Queue()
        cam_bp = blueprint_library.find('sensor.camera.rgb')
        lidar_bp = blueprint_library.find('sensor.lidar.ray_cast')
        imu_bp = blueprint_library.find('sensor.other.imu')
        gnss_bp = blueprint_library.find('sensor.other.gnss')

        # 可以设置一些参数 set the attribute of camera
        cam_bp.set_attribute("image_size_x", "{}".format(IM_WIDTH))
        cam_bp.set_attribute("image_size_y", "{}".format(IM_HEIGHT))
        cam_bp.set_attribute("fov", "60")
        # cam_bp.set_attribute('sensor_tick', '0.1')

        cam01 = world.spawn_actor(cam_bp, carla.Transform(carla.Location(z=args.sensor_h),carla.Rotation(yaw=0)), attach_to=ego_vehicle)
        cam01.listen(lambda data: sensor_callback(data, sensor_queue, "rgb_front"))
        sensor_list.append(cam01)

        cam02 = world.spawn_actor(cam_bp, carla.Transform(carla.Location(z=args.sensor_h),carla.Rotation(yaw=60)), attach_to=ego_vehicle)
        cam02.listen(lambda data: sensor_callback(data, sensor_queue, "rgb_right"))
        sensor_list.append(cam02)

        lidar_bp.set_attribute('channels', '64')
        lidar_bp.set_attribute('points_per_second', '200000')
        lidar_bp.set_attribute('range', '32')
        lidar_bp.set_attribute('rotation_frequency', str(int(1/settings.fixed_delta_seconds))) #
        
        lidar01 = world.spawn_actor(lidar_bp, carla.Transform(carla.Location(z=args.sensor_h)), attach_to=ego_vehicle)
        lidar01.listen(lambda data: sensor_callback(data, sensor_queue, "lidar"))
        sensor_list.append(lidar01)

        imu01 = world.spawn_actor(imu_bp, carla.Transform(carla.Location(z=args.sensor_h)), attach_to=ego_vehicle)
        imu01.listen(lambda data: sensor_callback(data, sensor_queue, "imu"))
        sensor_list.append(imu01)

        gnss01 = world.spawn_actor(gnss_bp, carla.Transform(carla.Location(z=args.sensor_h)), attach_to=ego_vehicle)
        gnss01.listen(lambda data: sensor_callback(data, sensor_queue, "gnss"))
        sensor_list.append(gnss01)
        #-------------------------- 传感器设置完毕 --------------------------#

        # 设置traffic manager
        tm = client.get_trafficmanager(args.tm_port)
        tm.set_synchronous_mode(True)



        while True:
            # Tick the server
            world.tick()

            # 将CARLA界面摄像头跟随车动
            loc = ego_vehicle.get_transform().location
            spectator.set_transform(carla.Transform(carla.Location(x=loc.x,y=loc.y,z=35),carla.Rotation(yaw=0,pitch=-90,roll=0)))


            w_frame = world.get_snapshot().frame
            print("\nWorld's frame: %d" % w_frame)
            try:
                rgbs = []

                for i in range (0, len(sensor_list)):
                    s_frame, s_name, s_data = sensor_queue.get(True, 1.0)
                    print("    Frame: %d   Sensor: %s" % (s_frame, s_name))
                    sensor_type = s_name.split('_')[0]
                    if sensor_type == 'rgb':
                        rgbs.append(_parse_image_cb(s_data))
                    elif sensor_type == 'lidar':
                        lidar = _parse_lidar_cb(s_data)
                    elif sensor_type == 'imu':
                        imu_yaw = s_data.compass
                    elif sensor_type == 'gnss':
                        gnss = s_data
                
                # 仅用来可视化 可注释
                rgb=np.concatenate(rgbs, axis=1)[...,:3]
                cv2.imshow('vizs', visualize_data(rgb, lidar, imu_yaw, gnss))
                cv2.waitKey(100)
                if rgb is None or args.save_path is not None:
                    # 检查是否有各自传感器的文件夹
                    mkdir_folder(args.save_path)

                    filename = args.save_path +'rgb/'+str(w_frame)+'.png'
                    cv2.imwrite(filename, np.array(rgb[...,::-1]))
                    filename = args.save_path +'lidar/'+str(w_frame)+'.npy'
                    np.save(filename, lidar)

            except Empty:
                print("    Some of the sensor information is missed")

    finally:
        world.apply_settings(original_settings)
        for sensor in sensor_list:
            sensor.destroy()
        for actor in actor_list:
            actor.destroy()
        print("All cleaned up!")

def mkdir_folder(path):
    for s_type in sensor_type:
        if not os.path.isdir(os.path.join(path, s_type)):
            os.makedirs(os.path.join(path, s_type))
    return True

def sensor_callback(sensor_data, sensor_queue, sensor_name):
    # Do stuff with the sensor_data data like save it to disk
    # Then you just need to add to the queue
    sensor_queue.put((sensor_data.frame, sensor_name, sensor_data))

# modify from world on rail code
def visualize_data(rgb, lidar, imu_yaw, gnss, text_args=(cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255,255,255), 1)):

    canvas = np.array(rgb[...,::-1])

    if lidar is not None:
        lidar_viz = lidar_to_bev(lidar).astype(np.uint8)
        lidar_viz = cv2.cvtColor(lidar_viz,cv2.COLOR_GRAY2RGB)
        canvas = np.concatenate([canvas, cv2.resize(lidar_viz.astype(np.uint8), (canvas.shape[0], canvas.shape[0]))], axis=1)

    # cv2.putText(canvas, f'yaw angle: {imu_yaw:.3f}', (4, 10), *text_args)
    # cv2.putText(canvas, f'log: {gnss[0]:.3f} alt: {gnss[1]:.3f} brake: {gnss[2]:.3f}', (4, 20), *text_args)

    return canvas
# modify from world on rail code
def lidar_to_bev(lidar, min_x=-24,max_x=24,min_y=-16,max_y=16, pixels_per_meter=4, hist_max_per_pixel=10):
    xbins = np.linspace(
        min_x, max_x+1,
        (max_x - min_x) * pixels_per_meter + 1,
    )
    ybins = np.linspace(
        min_y, max_y+1,
        (max_y - min_y) * pixels_per_meter + 1,
    )
    # Compute histogram of x and y coordinates of points.
    hist = np.histogramdd(lidar[..., :2], bins=(xbins, ybins))[0]
    # Clip histogram
    hist[hist > hist_max_per_pixel] = hist_max_per_pixel
    # Normalize histogram by the maximum number of points in a bin we care about.
    overhead_splat = hist / hist_max_per_pixel * 255.
    # Return splat in X x Y orientation, with X parallel to car axis, Y perp, both parallel to ground.
    return overhead_splat[::-1,:]

# modify from manual control
def _parse_image_cb(image):
    array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
    array = np.reshape(array, (image.height, image.width, 4))
    array = array[:, :, :3]
    array = array[:, :, ::-1]
    return array
# modify from leaderboard
def _parse_lidar_cb(lidar_data):
    points = np.frombuffer(lidar_data.raw_data, dtype=np.dtype('f4'))
    points = copy.deepcopy(points)
    points = np.reshape(points, (int(points.shape[0] / 4), 4))
    return points



if __name__ == "__main__":
    try:
        main(args)
    except KeyboardInterrupt:
        print(' - Exited by user.')


以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这份代码主要是通过CARLA提供的Python API来操控车辆,并且获取车辆周围的多个传感器数据。其中,还包括了对按键输入的响应,即可以通过键盘来手动控制车辆。

不过,根据你的描述,代码无法对生成的车辆进行人工控制,主要原因可能在于以下几点:

1.不确定代码是如何生成车辆的。代码中生成车辆的部分是这样实现的:

# 自动选择
transform_vehicle = random.choice(world.get_map().get_spawn_points())
ego_vehicle = world.spawn_actor(random.choice(blueprint_library.filter("model3")), transform_vehicle)

这里要注意用到的车辆模型是 "model3",且是随机选择生成位置的,如果这些参数无法满足你的需求,则无法在生成的车辆上进行控制。

2.控制方式的问题。代码中提供的是通过按键输入的方式进行手动控制,但是你并没有说明如何进行手动控制,是否已经使用了正确的按键,并且在执行代码时是否打开了Pygame窗口,以便能够响应按键输入。

综上所述,建议先检查一下生成的车辆是否正确,并且了解如何手动控制车辆。如果还无法解决问题,可以尝试将问题具体化,提供更多相关的信息,以便更好地定位问题。
如果我的回答解决了您的问题,请采纳!

该回答引用GPTᴼᴾᴱᴺᴬᴵ
根据您提供的代码,似乎是一个用于在Carla模拟环境中生成车辆并进行人工控制的Python代码。然而,代码中存在一些问题,可能导致无法成功实现人工控制。以下是可能的问题和改进建议:

  1. 未导入所需的Pygame库:在代码中使用了Pygame库来检测键盘事件以实现人工控制,但是在代码的开头并没有导入Pygame库。您需要在代码的开头添加import pygame语句,以便能够使用Pygame库的功能。
  2. 控制代码未放置在正确的位置:在代码中,控制代码(处理键盘事件和设置车辆控制参数)被放置在了__init__函数和process_control函数中,但是这两个函数没有被调用,因此控制代码不会被执行。您需要在合适的位置调用这两个函数,例如在主循环中或者在某个事件处理函数中调用。
  3. 代码中存在错误的语法和逻辑:在代码中存在一些错误的语法和逻辑,例如if语句和函数定义没有正确的缩进,缺少了一些必要的变量和方法调用,以及一些逻辑错误。您需要检查代码中的这些错误并进行修正,以确保代码能够正确执行。

以下是对代码的一些改进建议:

  1. 在代码的开头添加import pygame语句,以便能够使用Pygame库的功能。
  2. 在合适的位置调用__init__函数和process_control函数,例如在主循环中或者在某个事件处理函数中调用。
  3. 检查代码中的语法和逻辑错误,并进行修正,以确保代码能够正确执行。
  4. 检查车辆控制参数的设置是否正确,例如设置车辆的速度、转向角度、刹车状态等。
  5. 确保车辆控制参数的更新频率与模拟环境的时间步长相匹配,以确保车辆能够在正确的时间间隔内响应人工控制。

请注意,以上只是一些可能的问题和改进建议,具体的改进方式需要根据您的具体需求和代码的实际情况来决定。如果您需要更详细的帮助,请提供更多关于代码的详细信息和背景信息,以便我能够更好地帮助您解决问题。

引用chatGPT作答,这段代码中缺少了启动 Pygame 窗口的语句以及一个主循环,因此无法进行人工控制。需要添加如下代码来实现:

pygame.init()
pygame.font.init()

try:
    display = pygame.display.set_mode((IM_WIDTH, IM_HEIGHT), pygame.HWSURFACE | pygame.DOUBLEBUF)
    font = pygame.font.SysFont('Arial', 18)
except:
    pygame.display.set_mode((IM_WIDTH, IM_HEIGHT))
    display = pygame.display.set_mode((IM_WIDTH, IM_HEIGHT), pygame.HWSURFACE | pygame.DOUBLEBUF)
    font = pygame.font.SysFont('Arial', 18)

clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        control.parse_control(event)

    control.process_control()
    ego_vehicle.apply_control(control._control)
    world.tick()
    clock.tick(60)

    # Get the data of the sensors here and show them on the Pygame window

    # Update the Pygame window
    pygame.display.flip()

其中 control 是一个 VehicleControl 类型的对象,代表着我们希望控制的车辆。在循环中,我们首先处理 Pygame 的事件(键盘按键)以更新控制参数,然后将控制参数应用到车辆上,然后让仿真世界执行一次物理模拟,最后将传感器数据显示在 Pygame 窗口中并更新窗口。由于本代码是在类中实现的,需要将 Pygame 相关的代码移到类外并将 control 对象作为参数传入,然后修改 process_control 方法中的 self._ego_vehicle 为 self._vehicle。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7758862
  • 这篇博客你也可以参考下:执行python语言的三种方式(解释器,交互式,集成开发环境等)详解 简单易懂~
  • 您还可以看一下 jeevan老师的Python量化交易,大操手量化投资系列课程之内功修炼篇课程中的 讲师简介,量化交易介绍及自动化交易演示小节, 巩固相关知识点
  • 以下回答来自chatgpt:

    针对该问题,需要了解carla软件的API接口以及相关的python模块。在carla的Python API documentation中可以找到与人工控制车辆相关的模块和函数,具体如下:

    1. 相关模块:carla.VehicleControl, carla.VehicleRemoteControl

    2. 相关函数:apply_control(), remove_control_override()

    下面是一个示例代码,可以实现通过键盘输入来控制车辆的前进、后退、转向等行为,同时也可以通过代码指定控制车辆的速度、方向等参数,并将人工控制的结果实时输出到日志文件中:

    import carla
    import time
    
    def main():
        try:
            # 连接carla服务器
            client = carla.Client("localhost", 2000)
            client.set_timeout(10.0)
    
            # 获取世界对象
            world = client.get_world()
    
            # 获取所有车辆的列表
            vehicle_list = world.get_actors().filter('vehicle.*')
    
            # 获取第一个车辆并初始化remote_control
            vehicle = vehicle_list[0]
            remote_control = VehicleRemoteControl(vehicle)
    
            # 记录前一次状态
            previous_control = None
    
            # 开始执行循环
            while True:
                # 从键盘读取输入
                input = raw_input()
    
                # 处理输入并生成相应的控制命令
                control = None
                if input == "w":
                    control = carla.VehicleControl(throttle=1.0, steer=0.0)
                elif input == "s":
                    control = carla.VehicleControl(throttle=-1.0, steer=0.0)
                elif input == "a":
                    control = carla.VehicleControl(throttle=0.5, steer=-0.5)
                elif input == "d":
                    control = carla.VehicleControl(throttle=0.5, steer=0.5)
    
                # 如果当前输入有有效控制命令,就将其应用到车辆上
                if control is not None:
                    remote_control.apply_control(control)
                    previous_control = control
                # 如果当前输入无效,但前一次输入有控制命令,就取消车辆控制
                elif previous_control is not None:
                    remote_control.remove_control_override()
                    previous_control = None
    
                # 每100毫秒执行一次循环,以保证程序能随时响应输入
                time.sleep(0.1)
    
        except Exception as e:
            print(e)
    
    if __name__ == '__main__':
        main()
    

    同时,可以将程序的运行结果输出到日志文件中,代码如下:

    import carla
    import time
    
    def main():
        try:
            # 连接carla服务器
            client = carla.Client("localhost", 2000)
            client.set_timeout(10.0)
    
            # 获取世界对象
            world = client.get_world()
    
            # 获取所有车辆的列表
            vehicle_list = world.get_actors().filter('vehicle.*')
    
            # 获取第一个车辆并初始化remote_control
            vehicle = vehicle_list[0]
            remote_control = VehicleRemoteControl(vehicle)
    
            # 记录前一次状态
            previous_control = None
    
            # 打开日志文件
            log_file = open('log.txt', 'w')
    
            # 开始执行循环
            while True:
                # 从键盘读取输入
                input = raw_input()
    
                # 处理输入并生成相应的控制命令
                control = None
                if input == "w":
                    control = carla.VehicleControl(throttle=1.0, steer=0.0)
                elif input == "s":
                    control = carla.VehicleControl(throttle=-1.0, steer=0.0)
                elif input == "a":
                    control = carla.VehicleControl(throttle=0.5, steer=-0.5)
                elif input == "d":
                    control = carla.VehicleControl(throttle=0.5, steer=0.5)
    
                # 如果当前输入有有效控制命令,就将其应用到车辆上
                if control is not None:
                    remote_control.apply_control(control)
                    previous_control = control
                    print(control, file=log_file) #将人工控制的结果输出到日志文件中
                # 如果当前输入无效,但前一次输入有控制命令,就取消车辆控制
                elif previous_control is not None:
                    remote_control.remove_control_override()
                    previous_control = None
    
                # 每100毫秒执行一次循环,以保证程序能随时响应输入
                time.sleep(0.1)
    
        except Exception as e:
            print(e)
    
        finally:
            # 关闭日志文件
            log_file.close()
    
    if __name__ == '__main__':
        main()
    

    在代码中,我们使用了Python内置的print()函数将控制命令和程序运行状态输出到日志文件中,在实际应用中,也可以通过Python的logging模块实现更完善的日志记录和管理功能。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^