SDL2 窗口未关闭

问题描述 投票:0回答:1

我制作了一个简单的 ROS2 节点来移动机器人。

#include<unistd.h>

#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"

#include"SDL.h"

void cleanUp() {
    SDL_Quit();
    rclcpp::shutdown();
}

int main(int argc, char** argv) {

    rclcpp::init(argc,argv);

    auto node_ = rclcpp::Node::make_shared("keyboard_teleop");
    node_->declare_parameter("vx", 1.0);
    node_->declare_parameter("vtheta", 1.0);
    node_->declare_parameter("twist_topic", rclcpp::ParameterValue("/cmd_vel"));
    
    std::string twist_topic;
    node_->get_parameter("twist_topic", twist_topic);
    auto pub_ = node_->create_publisher<geometry_msgs::msg::Twist>(twist_topic, 10);
    
    double vx;
    double vtheta;
    node_->get_parameter("vx", vx);
    node_->get_parameter("vtheta", vtheta);

    geometry_msgs::msg::Twist robot_vel;
    SDL_Event event;
    
    if (SDL_Init(SDL_INIT_EVENTS) < 0)
    {
        fprintf(stderr, "Could not initialise SDL: %s\n", SDL_GetError());
        cleanUp();
        return 0;
    }

    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        fprintf(stderr, "Could not initialise SDL: %s\n", SDL_GetError());
        cleanUp();
        return 0;
    }

    SDL_Window* window = SDL_CreateWindow(
        "ROS Teleop",                  // window title
        SDL_WINDOWPOS_UNDEFINED,       // initial x position
        SDL_WINDOWPOS_UNDEFINED,       // initial y position
        100,                           // width, in pixels
        100,                           // height, in pixels
        SDL_WINDOW_OPENGL              // flags
    );

    if(window == nullptr)
    {
        fprintf(stderr, "Could not create SDL window: %s\n", SDL_GetError());
        cleanUp();
        return 0;
    }

    bool is_running{true};
    while (rclcpp::ok())
    {
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                // check if even is keyup or keydown
                case SDL_KEYDOWN:
                    // check which key was pressed
                    switch(event.key.keysym.sym)
                    {
                        case SDLK_w:
                            robot_vel.linear.x = vx;
                            break;
                        case SDLK_a:
                            robot_vel.angular.z = vtheta;
                            break;
                        case SDLK_s:
                            robot_vel.linear.x = -vx;
                            break;
                        case SDLK_d:
                            robot_vel.angular.z = -vtheta;
                            break;
                        default:
                            break;
                    }
                    break;
                case SDL_KEYUP:
                    // check which key was released
                    switch(event.key.keysym.sym)
                    {
                        case SDLK_w:
                            if(robot_vel.linear.x > 0.0)
                                robot_vel.linear.x = 0.0;
                            break;
                        case SDLK_a:
                            if(robot_vel.angular.z > 0.0)
                                robot_vel.angular.z = 0.0;
                            break;
                        case SDLK_s:
                            if(robot_vel.linear.x < 0.0)
                                robot_vel.linear.x = 0.0;
                            break;
                        case SDLK_d:
                            if(robot_vel.angular.z < 0.0)
                                robot_vel.angular.z = 0.0;
                            break;
                        default:
                            break;
                    }
                    break;
                case SDL_QUIT:
                    is_running = false;
                    break;
                default:
                    break;
            }
            if (!is_running)
            {
                break;
            }

            pub_->publish(robot_vel);
            usleep(10000); // 100Hz
        }

        if (!is_running)
        {
            break;
        }
    }
    

    SDL_DestroyWindow(window);
    cleanUp();
    return 0;
}

运行此代码将弹出一个黑色小窗口,您可以在其中使用 wasd 键来控制机器人。

问题是当我按右上角的 x 按钮时,窗口没有关闭。我读到按 x 键会发出

SDL_QUIT
事件,因此我编写了 case 语句来检测它并退出 while 循环,但它不起作用。

当我按 x 键时没有任何反应。我尝试将 print 语句放入

SDL_QUIT
的 case 语句中,但没有打印任何内容,这意味着永远不会发出
SDL_QUIT
信号。

这段代码有什么问题?

c++ sdl ros
1个回答
0
投票

我怀疑问题可能是由于程序中未使用 OpenGL 时使用

SDL_WINDOW_OPENGL
标志引起的。将其替换为
SDL_WINDOW_SHOWN
0
并查看是否有效。

© www.soinside.com 2019 - 2024. All rights reserved.