AirSim 自动驾驶仿真 (4) - 核心 APIs - C++

AirSim 自动驾驶仿真 (4) - 核心 APIs - C++

接下去主要介绍一下 AirSimAPIs 的使用. 官方 提供了 PythonC++ 两个版本, 我这里就主要以 C++ 来试验.

这篇文章的 Hello Car源码.


Hello Car 源码

官方文档该部分的源码还没有更新, 这里源码为 GitHub上的源码. 如果要用文档的例程, 需要把 两处

CarControllerBase::CarControls

改为

msr::airlib::CarApiBase::CarControls

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "common/common_utils/StrictMode.hpp"
STRICT_MODE_OFF
#ifndef RPCLIB_MSGPACK
#define RPCLIB_MSGPACK clmdep_msgpack
#endif // !RPCLIB_MSGPACK
#include "rpc/rpc_error.h"
STRICT_MODE_ON

#include "vehicles/car/api/CarRpcLibClient.hpp"
#include "common/common_utils/FileSystem.hpp"
#include <iostream>
#include <chrono>



int main()
{
    using namespace msr::airlib;

    std::cout << "Make sure settings.json has \"SimMode\"=\"Car\" at root. Press Enter to continue." << std::endl; std::cin.get();

    // This assumes you are running DroneServer already on the same machine.
    // DroneServer must be running first.
    msr::airlib::CarRpcLibClient client;
    typedef ImageCaptureBase::ImageRequest ImageRequest;
    typedef ImageCaptureBase::ImageResponse ImageResponse;
    typedef ImageCaptureBase::ImageType ImageType;
    typedef common_utils::FileSystem FileSystem;

    try {
        client.confirmConnection();

        std::cout << "Press Enter to get FPV image" << std::endl; std::cin.get();
        vector<ImageRequest> request = { ImageRequest("0", ImageType::Scene), ImageRequest("1", ImageType::DepthPlanner, true) };
        const vector<ImageResponse>& response = client.simGetImages(request);
        std::cout << "# of images received: " << response.size() << std::endl;

        if (response.size() > 0) {
            std::cout << "Enter path with ending separator to save images (leave empty for no save)" << std::endl;
            std::string path;
            std::getline(std::cin, path);

            for (const ImageResponse& image_info : response) {
                std::cout << "Image uint8 size: " << image_info.image_data_uint8.size() << std::endl;
                std::cout << "Image float size: " << image_info.image_data_float.size() << std::endl;

                if (path != "") {
                    std::string file_path = FileSystem::combine(path, std::to_string(image_info.time_stamp));
                    if (image_info.pixels_as_float) {
                        Utils::writePfmFile(image_info.image_data_float.data(), image_info.width, image_info.height,
                            file_path + ".pfm");
                    }
                    else {
                        std::ofstream file(file_path + ".png", std::ios::binary);
                        file.write(reinterpret_cast<const char*>(image_info.image_data_uint8.data()), image_info.image_data_uint8.size());
                        file.close();
                    }
                }
            }
        }

        //enable API control
        client.enableApiControl(true);
        CarApiBase::CarControls controls;

        std::cout << "Press enter to drive forward" << std::endl; std::cin.get();
        controls.throttle = 0.5f;
        controls.steering = 0.0f;
        client.setCarControls(controls);

        std::cout << "Press Enter to activate handbrake" << std::endl; std::cin.get();
        controls.handbrake = true;
        client.setCarControls(controls);

        std::cout << "Press Enter to take turn and drive backward" << std::endl; std::cin.get();
        controls.handbrake = false;
        controls.throttle = -0.5;
        controls.steering = 1;
        controls.is_manual_gear = true;
        controls.manual_gear = -1;
        client.setCarControls(controls);

        std::cout << "Press Enter to stop" << std::endl; std::cin.get();
        client.setCarControls(CarApiBase::CarControls());
    }
    catch (rpc::rpc_error&  e) {
        std::string msg = e.get_error().as<std::string>();
        std::cout << "Exception raised by the API, something went wrong." << std::endl << msg << std::endl; std::cin.get();
    }

    return 0;
}

Common APIS

以下方法均在类: msr::airlib::CarRpcLibClient

  • reset: 重置汽车回初始状态 (PS: 调用这个方法, 汽车会重新出现在出生点, 状态均重置) . 你必须在调用 reset 之后再次调用 enableApiControlarmDisarm

    (PS: 好像不调用这两个函数, 其他方法依然生效, 不晓得是不是版本更新过的缘故) .

  • confirmConnection: 每隔 1 秒检查链接状态, 并且在控制台输出连接进展.

  • enableApiControl: 处于安全原因, 默认禁止 API 控制自动驾驶汽车, 完全人工控制的 (通常通过 RC 或者 手柄模拟) . 用户必须调用这个函数去请求通过 API 控制. 这就像人工驾驶汽车可能禁止 API 控制, 意味着enableApiControl 是不起作用的. 这个可以通过isApiControlEnabled 来检查.

  • isApiControlEnabled: 返回 true 如果 API 控制被建立了. 如果是 false (默认设置), API 调用将会被忽略. 当成功调用enableApiControl, isApiControlEnabled 将返回 true.

    PS: 默认好像是 true.

  • ping: 如果建立连接, 这个调用将会返回 true, 否则会阻塞知道直到超时.

  • simPrintLogMessage: 在仿真窗口输出指定的 message. 如果 message_param也被提供, 那么也将输出. 如果这个 API 被调用时使用相同的 message值, 但是 message_param不同, 那么前一行将会被新行覆盖 (而不是创建新行来显示) . 举个例子, 当使用不同的 i 值调用 simPrintLogMessage("Iteration: ", to_string(i)) 时, 将在同一行保持更新. 合法的 severity 参数是 0 到 3, 分别以不同的颜色.

    PS: 不知道在哪儿看到这些输出日志).

  • simGetObjectPose, simSetObjectPose: 获取和设置 Unreal 环境中指定对象的位姿. 这里的对象表示 Unreal 术语中的 ”actor”. 它们通过标签 (tag) 和名称 (name) 来搜索. 请记住这些显示在 UE Editor 中的名称是每次运行时 自动生成 (auto-generated) 的, 并非永久的. 所以, 如果你想通过名称来引用 actor, 你必须在 UE Editor 中修改自动生成的名称. 你也可以在 Unreal Editor 中, 通过点击 actor 来完成对它添加一个标签. 然后去 Tags property , 点击 “+” 号, 添加一些字符串值. 如果多个 actors 有相同的标签, 那么第一个符合的将会被返回. 如果没有符合的对象被找到, 那么将会返回 NaN. 返回的位姿值是在以玩家出生点为原点的 NED 坐标系下的国际标准单位值. 对于simSetObjectPose, 指定的 actor 必须将 Mobility 设置为可移动, 否则你将得到未定义行为. simSetObjectPose 有一个 teleport 参数, 表示对象正在 moved through other objects (PS: 瞬移?) , 如果移动成功, 则返回 true.

    PS: 见下图,如果要获取这辆车的位姿,调用的参数名应该是 PhysXCar, 调用 SuvCarPawn-1 (自动生成的名称) 位姿值是 NaN

    msr::airlib::Pose pose_car = client.simGetObjectPose("PhysXCar");
    

    在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值