ตอนที่ 13: รีดไส้ติ่งประสิทธิภาพ! พื้นฐานการเขียน Node ด้วย C++ (roscpp / rclcpp)

1. 🎯 ตอนที่ 13: รีดเค้นประสิทธิภาพหุ่นยนต์ขั้นสุด! พื้นฐานการเขียน Node ด้วย C++
สวัสดีครับน้องๆ วิศวกรหุ่นยนต์ทุกคน! สองตอนที่ผ่านมาพี่ได้พาน้องๆ ไปลุยกับ Python จนสามารถสร้าง Publisher และ Subscriber กันได้แบบคล่องแคล่วแล้วใช่ไหมครับ?
แต่ในโลกความเป็นจริงของอุตสาหกรรมหุ่นยนต์ เมื่อเราต้องรับมือกับข้อมูลที่ไหลมาเป็นน้ำตก เช่น ภาพความละเอียดสูงจากกล้อง 60 fps หรือข้อมูล Point Cloud 3 มิติจาก LIDAR ถ้าน้องใช้ Python ประมวลผล… ไม่นานหน้าจอ Terminal ของน้องจะค้าง และ CPU จะวิ่งทะลุ 100% จนหุ่นยนต์เดินชนกำแพงแน่นอนครับ!
วันนี้พี่เลยจะพามาจับ “อาวุธหนัก” ของวงการหุ่นยนต์ นั่นคือการเขียน Node ด้วยภาษา C++ ผ่านไลบรารี rclcpp เตรียมตัวปลดล็อกความเร็วแสงให้หุ่นยนต์ของเรากันครับ!
2. 📖 เปิดฉาก (The Hook)
“แล้วทำไมเราไม่ใช้ Python ตลอดไปล่ะ ในเมื่อมันเขียนง่ายกว่าตั้งเยอะ?” นี่คือคำถามคลาสสิกที่พี่มักจะได้ยินจากน้องๆ เสมอครับ
จริงอยู่ที่ Python เป็นภาษาที่เป็นมิตรกับผู้เริ่มต้น (Beginner-friendly) และเหมาะมากสำหรับการทำตัวต้นแบบอย่างรวดเร็ว (Rapid prototyping) หรือการเขียนสคริปต์ทดสอบ แต่ข้อเสียของมันคือ Python เป็นภาษาแบบ “อินเทอร์พรีเตอร์” (Interpreted Language) ที่ต้องแปลโค้ดทีละบรรทัดตอนรัน ทำให้ทำงานช้ากว่ามาก
ในทางกลับกัน C++ คือภาษาแห่ง “ประสิทธิภาพ (Performance)” มันเป็นภาษาแบบ “คอมไพล์” (Compiled Language) ที่โค้ดทั้งหมดจะถูกแปลงเป็นภาษาเครื่อง (Machine-readable format) ตั้งแต่ก่อนรัน ทำให้มันทำงานได้เร็วปรื๊ด เข้าถึงทรัพยากรระดับต่ำ (Low-level) ได้ดีเยี่ยม เหมาะกับการทำ Real-time Control และการประมวลผลข้อมูลเซ็นเซอร์หนักๆ นี่แหละครับเหตุผลที่บริษัทหุ่นยนต์ระดับโลกถึงใช้ C++ เป็นภาษาหลัก!
3. 🧠 แก่นวิชา (Core Concepts)
ก่อนที่เราจะไปลุยโค้ด พี่ขอสรุปจุดที่แตกต่างอย่างชัดเจนระหว่างการเขียน Node ด้วย Python (rclpy) กับ C++ (rclcpp) ให้เห็นภาพก่อนครับ:
- 1. Smart Pointers (ระบบจัดการหน่วยความจำ):
ใน C++ ของ ROS 2 เราแทบจะไม่เห็นการใช้ Pointer แบบดิบๆ (Raw pointers) เลยครับ แต่เราจะใช้ Smart Pointers อย่าง
std::make_sharedหรือSharedPtrเพื่อช่วยจัดการหน่วยความจำ (Memory Management) แบบอัตโนมัติ ป้องกันปัญหา Memory Leak สุดปวดหัว! - 2. Object-Oriented Programming (OOP) มาตรฐานเดียว:
เช่นเดียวกับ Python โค้ด C++ ใน ROS 2 จะถูกบังคับให้เขียนในรูปแบบคลาส (Class) ที่สืบทอดมาจาก
rclcpp::Nodeทำให้โค้ดของเราเป็นระเบียบและนำไปใช้ซ้ำได้ง่าย - 3. คัมภีร์การประกอบร่าง (
CMakeLists.txt): นี่คือจุดที่ต่างจาก Python มากที่สุด! โค้ด C++ ไม่สามารถรันได้ทันที น้องๆ ต้องเขียนคู่มือสั่งให้ระบบสร้างไฟล์ Executable ผ่านไฟล์ที่ชื่อว่าCMakeLists.txtเสียก่อน ถ้าไม่เขียนไฟล์นี้ ต่อให้โค้ดเทพแค่ไหนcolcon buildก็จะมองไม่เห็นครับ

4. 💻 ร่ายมนต์โค้ดและคำสั่ง (Show me the Code)
เรามาดูหน้าตาของ Template โค้ด Node พื้นฐานในภาษา C++ กันครับ พี่จะคอมเมนต์อธิบายให้แบบบรรทัดต่อบรรทัด! (อย่าลืมว่าไฟล์นี้ต้องเซฟนามสกุลเป็น .cpp นะครับ)
1. โค้ด C++ Node พื้นฐาน (my_first_node.cpp):
#include "rclcpp/rclcpp.hpp" // ดึงไลบรารีหลักของ ROS 2 ฝั่ง C++ มาใช้
// สร้างคลาสของเราเอง โดยสืบทอด (Inherit) มาจาก rclcpp::Node
class MyCustomNode : public rclcpp::Node
{
public:
// Constructor ของคลาส: ทำหน้าที่ตั้งชื่อ Node ให้กับระบบ
MyCustomNode() : Node("my_cpp_node")
{
// พิมพ์ Log ข้อความออกมา (เทียบเท่ากับ self.get_logger().info ใน Python)
RCLCPP_INFO(this->get_logger(), "Hello World from C++ Node!");
}
private:
// ตรงนี้เอาไว้ประกาศตัวแปรต่างๆ เช่น Publisher, Subscriber หรือ Timer
};
// ฟังก์ชันหลักที่ระบบปฏิบัติการจะเรียกใช้งาน
int main(int argc, char **argv)
{
rclcpp::init(argc, argv); // สตาร์ทเครื่องยนต์ ROS 2
// สร้างอ็อบเจกต์ Node ของเราผ่าน Smart Pointer
auto node = std::make_shared<MyCustomNode>();
rclcpp::spin(node); // สั่งให้ Node หมุนวนทำงานไปเรื่อยๆ จนกว่าจะกด Ctrl+C
rclcpp::shutdown(); // ดับเครื่องยนต์ ROS 2
return 0;
}2. เวทมนตร์สั่งประกอบร่าง (CMakeLists.txt):
โค้ด C++ เขียนเสร็จแล้วต้องเอาไปสอนระบบให้คอมไพล์ด้วยครับ ให้น้องๆ เปิดไฟล์ CMakeLists.txt แล้วเพิ่มคำสั่งเหล่านี้ลงไป:
# 1. ค้นหาไลบรารี rclcpp ให้เจอ
find_package(rclcpp REQUIRED)
# 2. สั่งสร้างไฟล์รัน (Executable) ชื่อ 'test_node' จากไฟล์ซอร์สโค้ดของเรา
add_executable(test_node src/my_first_node.cpp)
# 3. บอกว่า 'test_node' ต้องใช้ไลบรารี rclcpp ในการทำงานนะ (พึ่งพาซึ่งกันและกัน)
ament_target_dependencies(test_node rclcpp)
# 4. นำไฟล์รันที่สร้างเสร็จแล้ว ไปเก็บไว้ในโฟลเดอร์ install/lib เพื่อให้ ros2 run หาเจอ!
install(TARGETS
test_node
DESTINATION lib/${PROJECT_NAME}/
)เมื่อเขียนเสร็จแล้ว ก็กลับไปที่ Root ของ Workspace แล้วสั่งรัน colcon build --packages-select <ชื่อ_package> ตามด้วย source install/setup.bash แล้วก็สั่ง ros2 run <ชื่อ_package> test_node ได้เลยครับ!
5. 🛡️ เคล็ดลับจากคัมภีร์ลับ (Under the Hood / Pro-Tips)
ในฐานะที่พี่เขียน C++ จนหัวฟูมาแล้ว นี่คือ “จุดตาย” ที่น้องๆ มักจะพลาดกันครับ:
- หลุมพราง
CMakeLists.txt: วิศวกรมือใหม่มักจะเขียนโค้ด C++ เสร็จแล้วสั่งcolcon buildเลย แล้วก็บ่นว่าหา Node ไม่เจอ! จำไว้เสมอครับว่า ถ้าสร้างไฟล์.cppใหม่ 1 ไฟล์ ต้องไปเพิ่มคำสั่งadd_executableและament_target_dependenciesใหม่อีก 1 ชุดเสมอ! ไม่งั้นระบบมันจะไม่คอมไพล์ให้ครับ - VS Code ขึ้นเส้นยึกยือสีแดง (Include Error):
ถ้าน้องๆ ใช้ VS Code เขียน C++ แล้วมันขีดเส้นใต้สีแดงตรง
#include "rclcpp/rclcpp.hpp"ไม่ต้องตกใจครับ! โค้ดไม่ได้ผิด แต่น้องต้องไปตั้งค่าไฟล์c_cpp_properties.jsonในโฟลเดอร์.vscodeให้ชี้ไปที่"/home/<user>/ros2_ws/install/**"ด้วย เพื่อให้โปรแกรมมองเห็นไลบรารีของ ROS 2 ครับ std::bindศิลปะแห่งการผูก Callback: ใน C++ เวลาเราจะสร้าง Timer หรือ Subscriber เราไม่สามารถส่งชื่อฟังก์ชันไปตรงๆ ได้เหมือน Python ครับ เราต้องใช้ฟังก์ชันที่ชื่อว่าstd::bind(&ClassName::function_name, this, _1)เพื่อ “ผูก” ฟังก์ชันเข้ากับคลาสปัจจุบันเสมอ นี่คือไวยากรณ์มาตรฐานของ C++11 ที่น้องๆ ต้องฝึกให้ชินครับ!
6. 🏁 บทสรุป (To be continued…)
การเขียน C++ อาจจะดูยุ่งยากกว่า Python เล็กน้อยตรงที่ต้องมานั่งจัดการ CMakeLists.txt และมีไวยากรณ์ที่เข้มงวด แต่สิ่งที่น้องๆ จะได้กลับมาคือ “ประสิทธิภาพ” ที่หาไม่ได้จากภาษาไหน มันสามารถรีดเร้นพลังของ CPU ได้อย่างเต็มเม็ดเต็มหน่วย ทำให้หุ่นยนต์ทำงานได้อย่างลื่นไหลไร้รอยต่อ
ตอนนี้น้องๆ มีอาวุธครบมือทั้งสาย “เร็วแต่กินแรง” อย่าง C++ และสาย “เขียนสบายใจ” อย่าง Python แล้ว! ในตอนต่อไป พี่จะพาเอา C++ มาสร้างการสื่อสารแบบ Topic (Publisher/Subscriber) แบบเจาะลึกกัน เตรียมตัวเปิด IDE แล้วมาลุยกันต่อครับ!
ต้องการที่ปรึกษาด้านการออกแบบสถาปัตยกรรมหุ่นยนต์ (Robotics) และระบบ Automation ให้กับองค์กรของคุณ? ทีมงาน WP Solution พร้อมให้บริการออกแบบและพัฒนาซอฟต์แวร์แบบครบวงจร ดูรายละเอียดบริการของเราได้ที่: www.wpsolution2017.com หรือพูดคุยปรึกษาเบื้องต้นได้ที่ Line: wisit.p