Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/issue 7 #8514

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 36 additions & 36 deletions Examples/CppClient/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,133 +18,133 @@
#include <carla/image/ImageView.h>
#include <carla/sensor/data/Image.h>

// 使用 Carla 模块的命名空间简化代码。
namespace cc = carla::client;
namespace cg = carla::geom;
namespace csd = carla::sensor::data;

using namespace std::chrono_literals;
using namespace std::string_literals;

// 简化断言宏,用于验证条件是否满足。
#define EXPECT_TRUE(pred) if (!(pred)) { throw std::runtime_error(#pred); }

/// Pick a random element from @a range.
/// 从给定范围中随机选择一个元素。
/// @param range 包含元素的范围。
/// @param generator 随机数生成器。
template <typename RangeT, typename RNG>
static auto &RandomChoice(const RangeT &range, RNG &&generator) {
EXPECT_TRUE(range.size() > 0u);
EXPECT_TRUE(range.size() > 0u); // 验证范围非空。
std::uniform_int_distribution<size_t> dist{0u, range.size() - 1u};
return range[dist(std::forward<RNG>(generator))];
}

/// Save a semantic segmentation image to disk converting to CityScapes palette.
/*
static void SaveSemSegImageToDisk(const csd::Image &image) {
using namespace carla::image;

char buffer[9u];
std::snprintf(buffer, sizeof(buffer), "%08zu", image.GetFrame());
auto filename = "_images/"s + buffer + ".png";

auto view = ImageView::MakeColorConvertedView(
ImageView::MakeView(image),
ColorConverter::CityScapesPalette());
ImageIO::WriteView(filename, view);
}
*/

/// 解析命令行参数,返回主机名和端口号。
/// @param argc 参数个数。
/// @param argv 参数值。
/// @return 包含主机名和端口号的元组。
static auto ParseArguments(int argc, const char *argv[]) {
EXPECT_TRUE((argc == 1u) || (argc == 3u));
EXPECT_TRUE((argc == 1u) || (argc == 3u)); // 参数必须为 1 或 3。
using ResultType = std::tuple<std::string, uint16_t>;
return argc == 3u ?
ResultType{argv[1u], std::stoi(argv[2u])} :
ResultType{"localhost", 2000u};
ResultType{"localhost", 2000u}; // 默认连接到 localhost:2000。
}

int main(int argc, const char *argv[]) {
try {

// 解析命令行参数,获取主机名和端口号。
std::string host;
uint16_t port;
std::tie(host, port) = ParseArguments(argc, argv);

// 初始化随机数生成器。
std::mt19937_64 rng((std::random_device())());

// 创建客户端并设置超时时间。
auto client = cc::Client(host, port);
client.SetTimeout(40s);

// 输出客户端和服务端的 API 版本。
std::cout << "Client API version : " << client.GetClientVersion() << '\n';
std::cout << "Server API version : " << client.GetServerVersion() << '\n';

// Load a random town.
// 随机选择一个可用的地图并加载。
auto town_name = RandomChoice(client.GetAvailableMaps(), rng);
std::cout << "Loading world: " << town_name << std::endl;
auto world = client.LoadWorld(town_name);

// Get a random vehicle blueprint.
// 从蓝图库中随机选择一个车辆蓝图。
auto blueprint_library = world.GetBlueprintLibrary();
auto vehicles = blueprint_library->Filter("vehicle");
auto blueprint = RandomChoice(*vehicles, rng);

// Randomize the blueprint.
// 随机化车辆蓝图的属性(如颜色)。
if (blueprint.ContainsAttribute("color")) {
auto &attribute = blueprint.GetAttribute("color");
blueprint.SetAttribute(
"color",
RandomChoice(attribute.GetRecommendedValues(), rng));
}

// Find a valid spawn point.
// 从推荐的生成点中随机选择一个位置。
auto map = world.GetMap();
auto transform = RandomChoice(map->GetRecommendedSpawnPoints(), rng);

// Spawn the vehicle.
// 在选定位置生成车辆。
auto actor = world.SpawnActor(blueprint, transform);
std::cout << "Spawned " << actor->GetDisplayId() << '\n';
auto vehicle = boost::static_pointer_cast<cc::Vehicle>(actor);

// Apply control to vehicle.
// 应用控制命令以使车辆前进。
cc::Vehicle::Control control;
control.throttle = 1.0f;
control.throttle = 1.0f; // 油门设为最大值。
vehicle->ApplyControl(control);

// Move spectator so we can see the vehicle from the simulator window.
// 调整观察者的位置以查看车辆。
auto spectator = world.GetSpectator();
transform.location += 32.0f * transform.GetForwardVector();
transform.location.z += 2.0f;
transform.rotation.yaw += 180.0f;
transform.rotation.pitch = -15.0f;
transform.location.z += 2.0f; // 提升视角高度。
transform.rotation.yaw += 180.0f; // 调整观察方向。
transform.rotation.pitch = -15.0f; // 向下倾斜视角。
spectator->SetTransform(transform);

/*
// Find a camera blueprint.
// 获取语义分割相机的蓝图。
auto camera_bp = blueprint_library->Find("sensor.camera.semantic_segmentation");
EXPECT_TRUE(camera_bp != nullptr);

// Spawn a camera attached to the vehicle.
// 在车辆上安装相机。
auto camera_transform = cg::Transform{
cg::Location{-5.5f, 0.0f, 2.8f}, // x, y, z.
cg::Rotation{-15.0f, 0.0f, 0.0f}}; // pitch, yaw, roll.
auto cam_actor = world.SpawnActor(*camera_bp, camera_transform, actor.get());
auto camera = boost::static_pointer_cast<cc::Sensor>(cam_actor);

// Register a callback to save images to disk.
// 注册回调函数,将语义分割图像保存到磁盘。
camera->Listen([](auto data) {
auto image = boost::static_pointer_cast<csd::Image>(data);
EXPECT_TRUE(image != nullptr);
SaveSemSegImageToDisk(*image);
});

// 模拟运行一段时间以捕获图像。
std::this_thread::sleep_for(10s);

// Remove actors from the simulation.
// 销毁相机。
camera->Destroy();
*/

// 销毁车辆。
vehicle->Destroy();
std::cout << "Actors destroyed." << std::endl;

} catch (const cc::TimeoutException &e) {
// 处理客户端超时异常。
std::cout << '\n' << e.what() << std::endl;
return 1;
} catch (const std::exception &e) {
// 处理其他异常。
std::cout << "\nException: " << e.what() << std::endl;
return 2;
}
Expand Down
22 changes: 20 additions & 2 deletions LibCarla/source/carla/Exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ namespace boost {
void throw_exception(
const std::exception &e,
boost::source_location const & loc) {
// =============================================================================
// -- 异常处理兼容性调整:Boost 和 Boost.Asio 的支持 ---------------------------
// =============================================================================

// 如果 Boost 被配置为禁用异常(BOOST_NO_EXCEPTIONS),
// 提供一个自定义的异常抛出实现。
#ifdef BOOST_NO_EXCEPTIONS

namespace boost {

// 自定义异常抛出函数。
// 需要开发者提供具体的异常抛出逻辑。
void throw_exception(const std::exception& e) {
// 在用户代码中实现具体逻辑。
throw_exception(e);
}

Expand All @@ -30,9 +44,11 @@ namespace boost {
#endif // BOOST_NO_EXCEPTIONS

// =============================================================================
// -- Workaround for Boost.Asio bundled with rpclib ----------------------------
// -- 针对 rpclib 使用的 Boost.Asio 的兼容性调整 -------------------------------
// =============================================================================

// 如果 Asio 被配置为禁用异常(ASIO_NO_EXCEPTIONS),
// 定义兼容性层以处理 Asio 中的异常抛出。
#ifdef ASIO_NO_EXCEPTIONS

#include <exception>
Expand All @@ -42,11 +58,13 @@ namespace boost {
namespace clmdep_asio {
namespace detail {

// 模板函数,用于抛出指定类型的异常。
template <typename Exception>
void throw_exception(const Exception& e) {
carla::throw_exception(e);
carla::throw_exception(e); // 调用 Carla 库提供的异常抛出实现。
}

// 针对常见异常类型的显式模板实例化。
template void throw_exception<std::bad_cast>(const std::bad_cast &);
template void throw_exception<std::exception>(const std::exception &);
template void throw_exception<std::system_error>(const std::system_error &);
Expand Down
Loading