C++ cho lập trình Robot – Phần 1


C++ cho lập trình Robot – Phần 1 – Làm quen với CMake: Nền tảng vững chắc cho ứng dụng Qt và Robotics của bạn

Lời mở đầu:

Chào mừng bạn đến với thế giới robot đầy thú vị! Nếu bạn đang chập chững bước đi trên con đường trở thành kỹ sư robot, việc nắm vững các công cụ xây dựng phần mềm là vô cùng quan trọng. Bài viết này sẽ như một người bạn đồng hành, hướng dẫn bạn từng bước cách sử dụng CMake và Qt – bộ đôi hoàn hảo để phát triển các ứng dụng robot mạnh mẽ, linh hoạt và dễ bảo trì. Chúng ta sẽ cùng nhau khám phá cách cấu hình CMake, tích hợp nó với Qt, và áp dụng vào các dự án robot thực tế. Sẵn sàng chưa? Cùng bắt đầu nhé!

Build System: “Người hùng thầm lặng” của mọi dự án phần mềm

Trước khi “nhảy” vào CMake, hãy dành chút thời gian để hiểu về “build system” (hệ thống xây dựng). Bạn có thể hình dung nó như một “nhạc trưởng” tài ba, điều phối quá trình biến mã nguồn (code) của bạn thành một ứng dụng hoàn chỉnh. Thay vì phải gõ hàng loạt câu lệnh phức tạp, bạn chỉ cần “ra lệnh” cho build system thông qua một file cấu hình, và nó sẽ lo phần còn lại.

Cụ thể, build system sẽ:

  1. Biên dịch mã nguồn: Chuyển đổi code C++ (hoặc ngôn ngữ khác) thành mã máy mà máy tính có thể “hiểu” được.
  2. Liên kết thư viện: Kết nối các thư viện cần thiết (như Qt, ROS, OpenCV…) vào ứng dụng của bạn.
  3. Tạo file thực thi: Tạo ra file .exe (trên Windows), file chạy được (trên Linux/macOS), hoặc ứng dụng nhúng trên robot.

CMake: “Chìa khóa vạn năng” cho các dự án đa nền tảng

CMake là một trình tạo hệ thống xây dựng (build system generator) mã nguồn mở và đa nền tảng. Nghe có vẻ “cao siêu”, nhưng thực ra nó rất thân thiện. CMake không trực tiếp build ứng dụng, mà nó tạo ra các file cấu hình cho các build system khác (như Make trên Linux/macOS, Ninja, hoặc Visual Studio trên Windows). Đây chính là “siêu năng lực” của nó: bạn chỉ cần viết file cấu hình CMake (CMakeLists.txt) một lần, và có thể build ứng dụng trên Windows, Linux, macOS, hoặc thậm chí trên các hệ thống nhúng của robot, mà không cần thay đổi code!

Tại sao CMake và Qt lại là “cặp bài trùng” cho Robotics?

  • C++ là ngôn ngữ “vua” trong Robotics: Hiệu năng cao, khả năng kiểm soát phần cứng tốt, và có vô số thư viện/framework hỗ trợ (ROS, OpenCV, PCL…).
  • Qt: Framework mạnh mẽ cho giao diện và hơn thế nữa: Qt không chỉ giúp bạn tạo giao diện người dùng (GUI) đẹp mắt, mà còn cung cấp các module hữu ích cho xử lý đa phương tiện, mạng, cơ sở dữ liệu… Nó không chỉ là về giao diện đẹp; nó là một bộ công cụ mạnh mẽ để xây dựng các ứng dụng hoàn chỉnh.
  • CMake giúp “gắn kết” C++ và Qt: CMake giúp quản lý các dependencies (phần phụ thuộc), cấu hình build cho các nền tảng khác nhau, và tích hợp với các công cụ của Qt (như uic cho file UI, moc cho phần mở rộng C++ của Qt, và rcc cho tài nguyên).
  • CMake là build system chính thức của ROS.

Cấu trúc thư mục chuẩn mực: Tổ ấm gọn gàng cho code của bạn

Một cấu trúc thư mục rõ ràng là “chìa khóa” để quản lý dự án hiệu quả. Dưới đây là một gợi ý “chuẩn không cần chỉnh” cho dự án CMake và Qt của bạn:

      MyRobotProject/
├── CMakeLists.txt        # "Trái tim" của dự án CMake
├── src/                  # Mã nguồn C++
│   ├── main.cpp          # Điểm khởi đầu của ứng dụng
│   ├── robot_control.h   # Header file cho lớp điều khiển robot
│   ├── robot_control.cpp # Code thực thi của lớp điều khiển robot
│   └── ...               # Các file code khác
├── include/              # (Tùy chọn) Header files public
│   └── MyRobotProject/  # Thư mục chứa các header files (khuyến nghị)
│       ├── robot_control.h
│       └── ...
├── ui/                   # Giao diện người dùng Qt (.ui)
│   ├── mainwindow.ui     # Giao diện chính
│   └── ...
├── resources/            # Tài nguyên (ảnh, âm thanh...)
│   ├── images/
│   │   ├── robot_icon.png
│   │   └── ...
│   ├── sounds/
│   │   ├── motor_sound.wav
│   │   └── ...
│   └── MyRobotProject.qrc # File resource Qt (.qrc)
├── tests/                # Kiểm thử (unit tests)
│   ├── CMakeLists.txt    # CMake file cho tests
│   ├── test_robot_control.cpp
│   └── ...
└── build/                # (Không cần commit) Nơi chứa các file build
    

Giải thích:

  • CMakeLists.txt: Chứa các lệnh để CMake build dự án.
  • src/: Tất cả code C++ của bạn “tụ họp” ở đây.
  • include/: (Không bắt buộc, nhưng rất nên dùng) Chứa các header files mà các file code khác có thể sử dụng.
  • ui/: Các file giao diện được thiết kế bằng Qt Designer.
  • resources/: Hình ảnh, âm thanh, và các tài nguyên khác.
  • tests/: Các bài kiểm tra (unit tests) để đảm bảo code của bạn chạy đúng.
  • build/: CMake sẽ tạo thư mục này để chứa các file tạm thời và kết quả build.

CMakeLists.txt: “Bí kíp” build dự án của bạn

Đây là file quan trọng nhất! Hãy cùng “mổ xẻ” một ví dụ CMakeLists.txt đơn giản:

      # Yêu cầu phiên bản CMake tối thiểu
cmake_minimum_required(VERSION 3.16)  # 3.21.1 trở lên nếu dùng Qt build tĩnh

# Đặt tên dự án, phiên bản, và ngôn ngữ
project(MyRobotProject VERSION 1.0.0 LANGUAGES CXX)

# Sử dụng chuẩn C++17 (hoặc mới hơn)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) # Báo lỗi nếu trình biên dịch quá cũ

# Tìm và import Qt (bắt buộc phải có Core, thêm Widgets nếu dùng GUI)
find_package(Qt6 REQUIRED COMPONENTS Core Widgets)

# Tự động gọi các công cụ của Qt (uic, moc, rcc)
qt_standard_project_setup()
# HOẶC: Gọi thủ công (ít dùng hơn)
# set(CMAKE_AUTOUIC ON)
# set(CMAKE_AUTOMOC ON)
# set(CMAKE_AUTORCC ON)

# Thêm include directories (nếu dùng thư mục include/)
include_directories(${CMAKE_SOURCE_DIR}/include)

# Liệt kê các file mã nguồn
set(SOURCE_FILES
    src/main.cpp
    src/robot_controller.cpp
)

# Liệt kê các file UI (nếu có)
set(UI_FILES
    ui/mainwindow.ui
)

# Liệt kê file resource (nếu có)
set(RESOURCES_FILES
    resources/MyRobotProject.qrc
)

# Tạo file thực thi (executable)
add_executable(MyRobotProject ${SOURCE_FILES} ${UI_FILES} ${RESOURCES_FILES})
# HOẶC (khuyên dùng cho Qt 6): qt_add_executable(MyRobotProject ...)

# Liên kết với các thư viện Qt
target_link_libraries(MyRobotProject PRIVATE Qt6::Core Qt6::Widgets)

# Dành cho ứng dụng Qt Widgets: tắt cửa sổ console trên Windows, tạo app bundle trên macOS
set_target_properties(MyRobotProject PROPERTIES
    WIN32_EXECUTABLE ON
    MACOSX_BUNDLE ON
)

Giải thích từng dòng lệnh:

  • cmake_minimum_required(…): Đảm bảo bạn đang dùng CMake đủ “xịn”.
  • project(…): Đặt tên, phiên bản, và ngôn ngữ cho dự án.
  • set(CMAKE_CXX_STANDARD …): Chọn chuẩn C++ (17 trở lên cho Qt 6).
  • find_package(Qt6 …): Tìm và “kết nối” với Qt.
  • qt_standard_project_setup(): Dòng lệnh “thần thánh” để tự động xử lý các công cụ Qt. Hoặc bạn có thể “điều khiển” thủ công bằng các lệnh set(CMAKE_AUTOUIC ON), set(CMAKE_AUTOMOC ON), set(CMAKE_AUTORCC ON).
  • include_directories(…): Thêm đường dẫn đến thư mục include/.
  • set(SOURCE_FILES …): Danh sách các file code C++.
  • set(UI_FILES …): Danh sách các file giao diện .ui.
  • set(RESOURCES_FILES …): Danh sách file resource .qrc.
  • add_executable(…) (hoặc qt_add_executable(…)): Tạo file thực thi từ các file đã liệt kê.
  • target_link_libraries(…): “Gắn” các thư viện Qt vào file thực thi.
  • set_target_properties: Ngăn chặn việc tạo một cửa sổ console trên Windows. Tạo một gói ứng dụng trên macOS.

Bắt tay vào build dự án:

  1. Tạo thư mục build/: (Thường nằm cùng cấp với CMakeLists.txt).
  2. Mở terminal/command prompt: Di chuyển đến thư mục build/.
  3. Chạy CMake: cmake .. (dấu .. nghĩa là “thư mục cha”, nơi chứa CMakeLists.txt).
  4. Build:
    • Trên Linux/macOS: make (hoặc ninja, nếu bạn đã cài đặt).
    • Trên Windows: Mở project bằng Visual Studio (nếu bạn đã chọn generator là Visual Studio), rồi build.

Ứng dụng Qt Quick (Tùy chọn, nhưng quan trọng cho giao diện hiện đại):

Nếu bạn đang sử dụng Qt Quick để có giao diện khai báo, hiện đại hơn, file CMakeLists.txt của bạn sẽ hơi khác một chút:

      cmake_minimum_required(VERSION 3.21.1) # Qt Quick thường nhắm đến thiết bị di động, do đó 3.21.1

project(MyRobotProject VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Quick) # Sử dụng Quick thay vì Widgets

qt_standard_project_setup(REQUIRES 6.5) # Thêm REQUIRES 6.5

include_directories(${CMAKE_SOURCE_DIR}/include)

set(SOURCE_FILES
    src/main.cpp
)

# Không có UI_FILES ở đây!

# Thêm file QML bằng qt_add_qml_module
qt_add_qml_module(MyRobotProject
    URI MyRobotProject  # Một định danh duy nhất cho module QML của bạn
    QML_FILES
        qml/main.qml  # File QML chính của bạn
        qml/RobotControlPanel.qml # Các file QML khác
    # RESOURCES  # Nếu bạn có tài nguyên được sử dụng bởi QML
    #  resources/MyRobotProject.qrc
)

add_executable(MyRobotProject ${SOURCE_FILES})
# HOẶC: qt_add_executable(MyRobotProject ${SOURCE_FILES})

target_link_libraries(MyRobotProject PRIVATE Qt6::Quick)
    

Khác biệt chính cho Qt Quick:

  • find_package(…): Chúng ta tìm Quick thay vì Widgets.
  • qt_add_qml_module(…): Lệnh này rất quan trọng cho Qt Quick. Nó cho CMake biết rằng bạn đang tạo một module QML, chỉ định các file QML và xử lý việc tạo các file cache QML cần thiết để tăng hiệu suất. URI là một định danh duy nhất cho module QML của bạn (giống như một namespace).
  • Không cần set_target_properties.

Thêm tài nguyên (Ảnh, v.v.):

Để sử dụng các tệp trong ứng dụng của bạn, chẳng hạn như hình ảnh, trước tiên bạn phải đưa chúng vào bằng Hệ thống tài nguyên Qt (Qt Resource System).

    # Thêm vào CMakeLists.txt của bạn
qt_add_resources(MyRobotProject resources
    PREFIX "/myresources"
    FILES
      resources/images/logo.png
      resources/sounds/beep.wav
)

Để tham chiếu các tệp đó, hãy thêm tiền tố tài nguyên đã chỉ định vào tên tệp.

      // Truy cập từ C++
logoLabel->setPixmap(QPixmap(":/myresources/logo.png"));
      // Truy cập từ qml
Image { source: "/myresources/logo.png" }  

Thêm bản dịch (Tùy chọn):

Để quốc tế hóa, sử dụng qt_add_translations():

    qt_add_translations(MyRobotProject
TS_FILES translations/MyRobotProject_vi.ts translations/MyRobotProject_en.ts)

Biên dịch chéo cho Robot của bạn (Nâng cao):

Nếu máy tính phát triển của bạn (ví dụ: máy tính xách tay của bạn) khác với nền tảng của robot (ví dụ: Raspberry Pi chạy Linux), bạn sẽ cần biên dịch chéo. Điều này đòi hỏi một toolchain file, cho CMake biết về trình biên dịch, thư viện và các công cụ khác của nền tảng đích.

Bạn cũng sẽ cần hai phiên bản Qt: một cho máy tính phát triển của bạn và một cho nền tảng đích. Qt Creator giúp việc này trở nên dễ dàng hơn với “Kits”, xác định môi trường xây dựng cho các nền tảng khác nhau.

Lời kết:

Chúc mừng bạn đã hoàn thành hành trình khám phá CMake và Qt! Giờ đây, bạn đã có trong tay “vũ khí” lợi hại để chinh phục thế giới robot. Hãy bắt đầu xây dựng những dự án robot tuyệt vời, và đừng quên chia sẻ thành quả của bạn với cộng đồng!

Tài liệu tham khảo:


Related Articles

Post a comment

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *