Dec 19, 2018

การใช้งาน XV-11 Lidar บน ROS kinetic

XV-11 Lidar คือ Lidar ของหุ่นยนต์ดูดฝุ่น Neato รุ่น XV-11 นั่นเอง ซึ่งหุ่นยนต์รุ่นนี้ได้เปิดตัวมาแล้วในปี 2010 ณ ขณะนี้ทางบริษัทก็ได้เลิกผลิตหุ่นยนต์รุ่นนี้ไปแล้ว แต่ชิ้นส่วนบางอย่างของมัน โดยเฉพาะ Lidar ยังคงมีประโยชน์อย่างมากสำหรับนักสร้างหุ่นยนต์ ซึ่ง Lidar นี้จะเป็นเซนเซอร์สำคัญอันหนึ่งในการสร้างแผนที่และระบุตำแหน่งไปพร้อมกัน หรือเรียกว่า SLAM นั่นเอง (Simultaneous localization and mapping) ซึ่ง XV-11 Lidar นี้สามารถหาซื้อมือสองได้จาก eBay ในราคาไม่เกิน $90 และ Lidar รุ่นนี้สามารถใช้กับ ROS ได้เป็นอย่างดี เพราะมี driver รองรับ

การสร้างอุปกรณ์เชื่อมต่อ

XV-11 Lidar ที่ซื้อมาจาก eBay นั้นยังไม่พร้อมใช้งาน โดยเราจะต้องสร้างอุปกรณ์สำหรับเชื่อมต่อดังภาพด้านล่าง ซึ่งประกอบไปด้วย

1. USB to Serial module - อุปกรณ์ชิ้นนี้มีบทบาทสำคัญ เพราะจะเป็นตัวแปลงสัญญาณข้อมูลจาก Lidar ส่งมายัง PC ผ่านพอร์ต USB โมดูลนี้โดยส่วนใหญ่จะให้ output power สองระดับ คือ 3.3V และ 5V ซึ่ง 3.3V จะเป็นไฟเลี้ยงสายสัญญาณ Serial นั่นเอง ส่วน 5V จะต้องถูกแปลงโดย Step down เป็นไฟ 3V เพื่อเลี้ยงมอเตอร์ของ Lidar โดยจะต้องเท่ากับ 3V แบบไม่ขาดไม่เกิน

2. Step down module - โมดูลนี้จะแปลงไฟ 5V ให้เหลือ 3V เพื่อขับมอเตอร์ของ Lidar ควรเลือกโมดูลที่สามารถปรับค่าได้ละเอียด

3. JST 2.0 PH 2-Pin connector สำหรับสาย power ของมอเตอร์ และ JST 2.0 PH 4-Pin connector สำหรับสายสัญญาณ Serial



เราสามารถสร้างอุปกรณ์ตาม diagram ด้านบนได้ตามอิสระ เพื่อความสะดวกและคงทน เราควรบัดกรีอุปกรณ์บน prototype pcb หรือ แผ่นไข่ปลา และทำที่ยึดด้วยแผ่นอคริลิก ตัวอย่างอุปกรณ์ที่ทำสำเร็จแล้วแสดงตามภาพ




ติดตั้ง xv_11_laser_driver
เมื่อสร้าง hardware เรียบร้อยแล้ว ขั้นตอนต่อไปก็การติดตั้ง ROS package สำหรับ XV-11 Lidar ผมใช้ ROS kinetic ใน Ubuntu Mate 16.04 บน Raspberry Pi 3 B ดังนั้น คำสั่งในการติดตั้ง driver XV-11 คือ

$ sudo apt-get install ros-kinetic-xv-11-laser-driver

สร้าง udev rules (optional)

ขั้นตอนนี้ถือเป็น optional เพราะชื่อพอร์ตของ XV-11 จะขึ้นอยู่กับโมดูล USB Serial ที่เราใช้ โดยปกติจะเป็น /dev/ttyUSB0 หรือ /dev/ttyACM0 แต่เพื่อให้เกิดความสะดวกในการเรียกชื่อพอร์ตของ XV-11 เราจะสร้างไฟล์สำหรับ udev rule ดังนี้

- ใช้คำสั่ง $ lsusb เพื่อดู idVender และ idProduct ตามภาพ


- จากนั้นใช้คำสั่ง text editor อย่างเช่น $ sudo pluma ใน Ubuntu Mate เพื่อสร้างไฟล์และบันทึกลงใน /etc/udev/rules.d/52-lidar.rules แล้วใส่เนื้อหาตามตัวอย่าง โดย idVender และ idProduct ของแต่ละคนอาจจะไม่เหมือนกัน

SUBSYSTEMS=="usb", KERNEL=="ttyUSB[0-9]*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="lidar"

- เมื่อ reboot เราจะพบว่ามีพอร์ต /dev/lidar เกิดขึ้น

สร้าง launch file

ในกรณีที่เรามี ROS workspace อยู่แล้ว ให้สร้าง launch file ขึ้นมาเพื่อความสะดวกในการสร้างโหนด XV-11 Lidar สมมุติว่าชื่อ test_laser.launch ดังตัวอย่าง

<?xml version="1.0"?>

<launch>
    <node pkg="xv_11_laser_driver" type="neato_laser_publisher" name="xv_11_laser_driver">
      <param name="port" value="/dev/lidar"/>
      <param name="firmware_version" value="2"/>
      <param name="frame_id" value="laser"/>
    </node>
</launch>

ทดสอบ XV-11 lidar

เมื่อผ่านขั้นตอนต่างๆ มากมายมาแล้ว คราวนี้เราทดสอบ XV-11 Lidar ของเรากัน

- รันโหนดด้วยคำสั่ง

$ roslaunch package_name test_laser.launch

โดยที่ package_name ตามที่เราสร้าง

- ดูค่า scan ด้วย rviz

รันคำสั่ง rviz จากนั้น Add by topic เลือก /scan ดังภาพ


แก้ไขตรง Fixed Frame เป็น /laser เราก็จะเห็นข้อมูลที่ XV-11 Lidar สแกนได้ ดังภาพ



เอกสารอ้างอิง
http://wiki.ros.org/xv_11_laser_driver/Tutorials/Running%20the%20XV-11%20Node
http://meetjanez.splet.arnes.si/2015/08/22/neato-xv-11-to-ros-slam

Nov 10, 2018

Ubuntu 16.04 และ ROS Kinetic บน MECOOL VS-RK3399



MECOOL VS-RK3399 เป็นบอร์ด rockchip ราคาประหยัดที่หาซื้อได้จาก AliExpress ในราคาต่ำกว่า $100 หรือ 3,000 บาท (ณ ตอนที่ผมซื้อ) ในชุดมีอุปกรณ์ครบตามภาพด้านล่าง ประกอบด้วย เคสอคริลิก อะแดปเตอร์ 12V เสาอากาศ รีโมท ได้ทุกอย่างครบชุดในราคานี้ถือว่าคุ้มมาก


สเปคของบอร์ด MECOOL VS-RK3399 ถือว่าไม่น้อยหน้าแบรนด์อื่นในรุ่นเดียวกัน รายละเอียดตามภาพ ซึ่งเหมาะที่จะมาใช้กับ ROS และงานด้าน machine vision กับ AI


ในส่วนของซอฟต์แวร์สำหรับบอร์ดนี้ก็ถือว่าไม่ลำบากนัก บอร์ดมาพร้อมกับ Android สำหรับ Smart TV สามารถรีวิวได้จาก CNX-Software (Part 1 และ Part 2)

แต่เป้าหมายสำหรับผม คือ การติดตั้ง ROS บนบอร์ดนี้ และพบว่ามันสามารถทำงานได้ดี ผมขอสรุปขั้นตอนดังนี้

การแฟลช Ubuntu 16.04 

1. เราสามารถเข้าไปโหลด Ubuntu 16.04 image จากได้ MEGA ของ Videostrong ตามภาพ


2. จากนั้นผมก็ทำตามขั้นการแฟลช Debian image จาก CNX-Software แต่แค่เปลี่ยนมาเป็น Ubuntu เท่านั้น ก่อนอื่นเราต้องโหลด upgrade_tool ก่อน จากนั้นก็แตกไฟล์ทั้ง upgrade_tool และ Ubuntu image ไปไว้ในโฟล์เดอร์เดียวกัน

3. เปิดใช้งานบอร์ดโดยการเสียบกับอแดปเตอร์ 12V ที่ได้มาในชุด ต่อจอ HDMI รวมทั้งเมาส์และคีย์บอร์ด จากนั้นต่อสาย USB type C to USB 3.0 ที่มากับชุดอยู่แล้วเข้ากับบอร์ด และ PC ของเรา จากนั้นกดปุ่ม recovery ค้างไว้ แล้วตามด้วยปุ่ม reset นับในใจ 1 2 3 แล้วปล่อยทุกปุ่ม บอร์ดก็จะเข้าสู่โหมดการแฟลช

4. ตรวจสอบว่า PC ของเราพบบอร์ดหรือยัง ด้วยคำสั่ง sudo ./upgrade_tool ซึ่งเราจะพบข้อความว่าพบบอร์ดแล้ว จากนั้นแฟลช Ubuntu ด้วยคำสั่ง upgrade_tool uf VS-RK3399-UbuntuOS20180306.img

การใช้งาน Ubuntu 16.04 และแก้ปัญหาเบื้องต้น

หลังจากแฟลชเรียบร้อยบอร์ดก็จะบูทเข้า Ubuntu 16.04 ดังภาพ เมื่อบูทมาเข้ามาก็อย่าตกใจว่าทำไมมีแต่หน้าจอโล่งๆ มันเป็นธีมของเขา น่าจะเป็น Xfce4 desktop ส่วนกล่องข้อความก็แค่แจ้งข้อผิดพลาดเกี่ยวกับ Bluetooth ซึ่งเรายังไม่ได้เปิดใช้งาน


วิธีการกำจัดกล่องข้อความตามภาพดา้นบน คือ 2 คำสั่งนี้
$ sudo chmod 4754 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
$ sudo chown root:messagebus /usr/lib/dbus-1.0/dbus-daemon-launch-helper

เมนูการใช้งานจะซ่อนอยู่ในปุ่มเมาส์ขวา ลองคลิ๊กดูก็จะพบภาพนี้


ผมเชื่อมต่อ WiFi โดยการเข้าไปที่ Application->Settings->Network Connections ซึ่งมันไม่มี AP list เหมือนอย่างใน Ubuntu ปกติ เราต้อง Add แล้วเลือก WiFi และใส่ข้อมูลเอง ในแทบ WiFi ใส่ SSID เป็นชื่อ AP ของเรา ส่วน Device เลือกเป็น wlan0 ต่อมาแทบ WiFi Security เลือก WPA & WPA2 Personal และใส่ password สุดท้ายกดปุ่ม Save บอร์ดก็จะเข้า WiFi ทันที เมื่อเข้า WiFi ก็อย่าลืม sudo apt update และ sudo apt upgrade เพื่ออัพเดท Ubuntu ล่าสุดด้วย

ตรวจสอบทรัพยากรของเครื่องด้วย htop
$ sudo apt install htop
$ htop

เราจะพบว่าบอร์ดมี CPU จำนวน 6 คอร์ และมี RAM 4 GB ตรงตามสเปค ในรูปด้านล่างนี้ ว้าว!!


default user ของบอร์ดนี้ คือ videostrong โดยที่บอร์ดนี้ได้ตั้งค่า auto login ไว้ ซึ่งไม่ปลอดภัย อันดับแรกสุดเราต้องสร้าง root password ก่อน แล้วตามด้วยสร้าง sudo user ใหม่ขึ้นมาอีกอัน ด้วยคำสั่ง
$ su passwd
$ sudo adduser <username>
$ sudo usermod -aG sudo <username>

โดยที่ <username> คือชื่อที่เรากำหนด ในกรณีของผมคือ ubuntu จากนั้นแก้ไข auto login ดังนี้
$ sudo geany /etc/lightdm/lightdm.conf.d/12-autologin.conf

แล้วใส่เนื้อหาดังนี้
[SeatDefaults]
autologin-user=
#user-session=xfce4-session
allow-guest=false

เราควรแก้ไข /etc/sudoers โดยให้ลบ  NOPASSWD: ออกไปด้วย ถ้าพบข้อความนี้ sudo: /etc/sudoers.d is world writable ให้พิมพ์คำสั่ง
$ pkexec chmod 555 /etc/sudoers.d
$ pkexec chmod 555 /etc/sudoers.d/README

ควรแก้ไขชื่อเครื่องในไฟล์ /etc/hostname และ /etc/hosts ด้วย text editor อย่าง Geany ($sudo apt install geany) จาก videostrong เป็นชื่อที่เราจำได้ง่าย ของผมคือ turtlebot นั่นเอง

ผมพบความผิดปกติอย่างหนึ่งคืออยู่ๆก็ disk full จากการตรวจสอบด้วยคำสั่ง sudo du -sh * เริ่มจาก / พบว่าตัวปัญหา คือ ไฟล์ /var/log/cups/error_log ที่เพิ่มขนาดอย่างไม่ทราบสาเหตุ วิธีแก้คือ
$ sudo systemctl stop cups
$ sudo systemctl stop cups-browsed
$ sudo systemctl disable cups
$ sudo systemctl disable cups-browsed
$ sudo systemctl disable cups.socket cups.path cups.service
$ sudo systemctl stop cups.service
$ sudo rm /var/log/cups/error_log

การแก้ปัญหา panel ไม่ปรากฏ ก่อนอื่นเราต้องเลือกจอภาพให้ถูกก่อนจาก Settings->Display ในกรณีของผมคือจอที่ 2


จากนั้นก็ไปที่ Settings->Panel ตรงแทบ Dispaly ให้เลือก Output ให้ตรงกับจอภาพของเรา ของผมคือ Monitor 2


ในที่สุด Panel ก็จะแสดงขึ้นมาที่ด้านบนของ Desktop ทำให้ใช้งานสะดวกขึ้น ตามภาพ


การติดตั้ง ROS

การติดตั้ง ROS Kinetic บนบอร์ดนี้ก็ไม่ต่างกับติดตั้ง ROS บน Ubuntu ทั่วไป ผมขอสรุปคำสั่งดังนี้

$ sudo c_rehash /etc/ssl/certs
$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
$ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
$ sudo apt-get update
$ sudo apt-get install ros-kinetic-desktop-full
$ sudo rosdep init
$ rosdep update
$ echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
$ source ~/.bashrc
$ sudo apt-get install python-rosinstall python-rosinstall-generator python-wstool build-essential

สุดท้ายก็รันคำสั่ง roscore จะพบภาพด้านล่างนี้ มันแสดงให้เห็นว่าบอร์ดนี้ก็สามารถติดตั้ง ROS ได้ ส่วนการทดสอบขั้นต่อไปก็ คือ การนำไปงานใช้กับหุ่นยนต์จริง อย่างเช่น TurtleBot เป็นต้น


Jul 14, 2018

การติดตั้ง Arduino_STM32 และ ROS สำหรับ Maple Mini (STM32F103CBT6)

ภาพจาก stm32duino.com

Maple Mini เป็นบอร์ดไมโครคอนโทรลเลอร์ 32 บิทราคาถูกที่หาซื้อได้ทั่วไปจาก AliExpress ในราคา ~$3.3 หรือ ~120 บาท ซึ่งราคาถูกมากเทียบกับประสิทธิภาพ คุณสมบัติสำคัญของบอร์ดนี้ คือ ใช้ชิป STM32F103CBT6 มี Flash 128 KB RAM 20 KB ความเร็ว 72 MHz ซึ่งเพียงพอต่อการเขียนเฟิร์มแวร์สำหรับ ROS บอร์ดนี้ทำงานที่ 3.3V แต่ก็มีบาง pin ที่รับอิพุท 5V ได้ด้วย ซึ่งสามารถทำงานได้กับเซนเซอร์ 5V บางตัว เช่น Hall sensor encoder หรือ Ultrasonic sensor  HC-SR04 บอร์ดอัพโหลดโปรแกรมผ่าน mini USB ได้โดยตรงไม่ต้องใช้ ST-Link ดังนั้นบอร์ดนี้จึงเหมาะที่จะนำมาเป็น base controller สำหรับหุ่นยนต์ ROS


ติดตั้ง Arduino_STM32

Arduino_STM32 เป็นซอฟต์แวร์ที่ทำให้เราสามารถเขียนโปรแกรมสำหรับบอร์ด STM32F103 ด้วย Arduino IDE  ผมได้สรุปวิธีการติดตั้งจากเวบไซต์ของ Arduino_STM32  ดังนี้ โดยผมใช้ระบบปฏิบัติการ Ubuntu 16.04 LTS

1. ติดตั้ง Arduino IDE สำหรับ Linux ตามคำสั่งนี้

2. เปิด Arduino IDE ขึ้นมา ไปที่ Tools->Boards manager เลือกติดตั้ง Arduino SAM boards (Cortex-M3) ขั้นตอนนี้ต้องทำเพราะมีการติดตั้ง arm-none-eabi-g++ toolchain ด้วย

3. ดาวน์โหลด Arduino_STM32 แล้วแตกไฟล์ในไปไว้ในโฟลเดอร์ hardware ของ Arduino IDE สุดท้ายเราจะได้ ~/Arduino/hardware/Arduino_STM32

4. รัน ~/Arduino/hardware/Arduino_STM32/tools/linux/install.sh เพื่อติดตั้ง udev rules

5. ปิดและเปิด Arduino IDE ขึ้นมาใหม่อีกครั้ง เลือก Tools->Board เราก็จะพบว่ามี Maple Mini รวมทั้งบอร์ด STM32 อื่นๆ ที่สนับสนุนให้เลือก ตามภาพ


ถึงตอนนี้ก็เป็นอันว่าเราสามารถเขียนโปรแกรมในสไตล์ Arduino สำหรับบอร์ด Maple Mini ได้แล้ว ซึ่งการเขียนโปรแกรมไม่แตกต่างจากบอร์ด UNO เลย เพียงแต่ต้องศึกษา pinout จากเวบไชต์ stm32duino.com ตามภาพ
 
ภาพจาก stm32duino.com


ติดตั้ง ros_lib สำหรับ Arduino

ros_lib เป็น library ของ ROS สำหรับ Arduino ซึ่งทำให้เราสร้าง node และส่งข้อมูลผ่าน Serial port จากบอร์ด Microcontroller มายัง PC หรือ Raspberry Pi ได้ ซึ่งวิธีการติดตั้ง ros_lib สำหรับ Ubuntu 16.04 LTS และ ROS kinectic มีดังนี้

1. ติดตั้ง rosserial
sudo apt-get install ros-kinetic-rosserial-arduino
sudo apt-get install ros-kinetic-rosserial

2. ติดตั้ง ros_lib
cd ~/Arduino/libraries
rm -rf ros_lib #ลบไฟล์เก่า (ถ้ามี)
rosrun rosserial_arduino make_libraries.py .

3. ปิดแล้วเปิด Arduino IDE ขึ้นมาใหม่ ถ้าการติดตั้งไม่ผิดพลาดเราจะเห็น ros_lib ใน File->Examples ดังภาพ



หลังจากติดตั้ง ros_lib สำหรับ Maple Mini แล้ว ต่อจากนี้ไปก็ศึกษาการเขียนโปรแกรมตามเวบนี้ rosserial_arduino Tutorials

ROS networking แบบไม่ต้องจำ IP address

ในการตั้งค่า network เพื่อควบคุมหุ่นยนต์ ROS แบบ remote ผ่าน WiFi ผมประสบปัญหาอย่างหนึ่ง คือ บางครั้ง router มันเปลี่ยนค่า IP address ของเครื่องคอมพิวเตอร์ หรือ บางทีก็จำ IP address ไม่ได้บ้าง ในเวบนี้มีวิธีแก้ปัญหา คือ แทนที่จะจำ IP address เรามาจำชื่อ url กันดีกว่า เช่น ssh ubuntu@myrobot.local แทนที่จะเป็น ssh ubuntu@192.168.0.1

1. ตั้งชื่อคอมพิวเตอร์ทั้งเครื่อง local และ remote โดยการแก้ไขไฟล์ /etc/hostname และ /etc/hosts

2. ติดตั้ง zeroconf ทั้งในเครื่องคอมพิวเตอร์ local และ remote
sudo apt-get install netatalk
sudo apt-get install avahi-daemon
sudo update-rc.d avahi-daemon defaults

3. ทดสอบการเชื่อมต่อ
ping local-pc.local
ping myrobot.local

4. ตั้งค่าในไฟล์ .bashrc
ในเครื่อง local เพิ่ม
export ROS_MASTER_URI=http://myrobot.local:11311
export ROS_HOSTNAME=local-pc.local

ในเครื่อง remote ที่ติดไปกับหุ่นยนต์ เพิ่ม
export ROS_MASTER_URI=http://localhost:11311
export ROS_HOSTNAME=myrobot.local

อย่าลืม source .bashrc หลังบันทึกไฟล์แล้ว

5. ตอนนี้เราก็สามารถ ssh แบบไม่ต้องจำ IP address ได้เช่นกัน
ssh username@myrobot.local

ถ้าไม่อยากใส่ password ในการ ssh ทุกครั้ง อ่านบทความนี้

SSH login แบบไม่ต้องใส่ password ทุกครั้ง

การ login เพื่อไปรันโหนดของ ROS ในเครื่อง remote ที่ติดไปกับตัวหุ่นยนต์ เช่น Raspberry Pi หรือ Mini PC หรือ Netbook ก็ตาม เราต้อง ssh กันบ่อยๆ ถ้าต้องใส่ password ทุกครั้งก็เสียเวลา ในเวบนี้มีวิธีแก้ปัญหานี้ สมมุติว่าที่เครื่อง local คอมพิวเตอร์ของเราชื่อ A โดย username คือ a ส่วน remote คอมพิวเตอร์ที่ติดไปกับตัวหุ่นยนต์ชื่อ B โดย username คือ b

1. สร้างคีย์ที่เครื่อง local
a@A:~> ssh-keygen -t rsa

2. คัดลอกคีย์ไปที่เครื่อง remote
a@A:~> ssh b@B mkdir -p .ssh
a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'

3. login เครื่อง remote ด้วยคำสั่ง
a@A:~> ssh b@B

ถ้าไม่ได้ผล อาจจะขึ้นอยู่กับเวอร์ชั่นของ SSH ด้วย ในบางระบบอาจจะต้องแก้ไข คือ

  • เพิ่มคีย์ใน .ssh/authorized_keys2 แทน
  • เปลี่ยนโหมด .ssh เป็น 700
  • เปลื่ยนโหมด .ssh/authorized_keys2 เป็น 640