• Tidak ada hasil yang ditemukan

BAB V HASIL DAN PEMBAHASAN

5.2 Komunikasi Serial Menggunakan Rosserial

Rosserial adalah sebuah perangkat lunak yang memungkinkan komunikasi serial antara perangkat keras mikrokontroler, seperti Arduino, dengan sistem ROS (Robot Operating System).

Dengan menggunakan rosserial dapat mengintegrasikan perangkat keras mikrokontroler dengan

ekosistem ROS untuk mengontrol robot atau perangkat lain secara lebih terstruktur dan terintegrasi.

Langkah awal dalam implementasi komunikasi serial adalah membuat sebuah ROS node. Node ini bertanggung jawab untuk mengatur komunikasi antara mikrokontroler dan sistem ROS. Penulis menggunakan bahasa pemrograman Python untuk membuat node ini. Node ini akan berperan dalam menginisialisasi komunikasi, mengirim pesan, dan menerima pesan. Selanjutnya adalah membuat node baru yang digunakan sebagai subscriber yang akan menerima pesan yang dikirimkan dari komunikasi serial. Dalam hal ini program pada Arduino berperan sebagai node subscriber yang akan menerima pesan dari publisher. Program Arduino akan menggerakkan roda kendaraan sesuai dengan pesan yang diterima. Komunikasi serial menggunakan rosserial dapat dijalankan ketik node yang berperan dalam menginisialisasi komunikasi telah dijalankan dan selanjutnya node subscriber pada Arduino dijalankan. Pada tahap berikutnya adalah membuat node baru yang berperan sebagai publisher yang akan mengirimkan data informasi. Dalam hal ini publisher adalah node yang terhubung ke Indoor GPS dan akan mengirimkan data informasi dari beacon dinamis.

 Kode Program serial Node/ROS Node

#!/usr/bin/env python import rospy

from rosserial_python import SerialClient, RosSerialServer from serial import SerialException

from time import sleep import multiprocessing import sys

if __name__=="__main__":

rospy.init_node("serial_node")

rospy.loginfo("ROS Serial Python Node")

port_name = rospy.get_param('~port','/dev/ttyUSB0') baud = int(rospy.get_param('~baud','57600'))

# for systems where pyserial yields errors in the fcntl.ioctl(self.fd, TIOCMBIS,

\

# TIOCM_DTR_str) line, which causes an IOError, when using simulated port fix_pyserial_for_test = rospy.get_param('~fix_pyserial_for_test', False)

# Allows for assigning local parameters for tcp_port and fork_server with # global parameters as fallback to prevent breaking changes

if(rospy.has_param('~tcp_port')):

tcp_portnum = int(rospy.get_param('~tcp_port')) else:

tcp_portnum = int(rospy.get_param('/rosserial_embeddedlinux/tcp_port', '11411'))

if(rospy.has_param('~fork_server')):

fork_server = rospy.get_param('~fork_server') else:

fork_server = rospy.get_param('/rosserial_embeddedlinux/fork_server', False)

# TODO: do we really want command line params in addition to parameter server params?

sys.argv = rospy.myargv(argv=sys.argv) if len(sys.argv) >= 2 :

port_name = sys.argv[1]

if len(sys.argv) == 3 :

tcp_portnum = int(sys.argv[2])

if port_name == "tcp" :

server = RosSerialServer(tcp_portnum, fork_server)

rospy.loginfo("Waiting for socket connections on port %d" % tcp_portnum) try:

server.listen() except KeyboardInterrupt:

rospy.loginfo("got keyboard interrupt") finally:

rospy.loginfo("Shutting down")

for process in multiprocessing.active_children():

rospy.loginfo("Shutting down process %r", process) process.terminate()

process.join()

rospy.loginfo("All done")

else : # Use serial port while not rospy.is_shutdown():

rospy.loginfo("Connecting to %s at %d baud" % (port_name,baud) ) try:

client = SerialClient(port_name, baud, fix_pyserial_for_test=fix_pyserial_for_test)

client.run()

except KeyboardInterrupt:

break

except SerialException:

sleep(1.0) continue except OSError:

sleep(1.0) continue except:

rospy.logwarn("Unexpected Error: %s", sys.exc_info()[0]) client.port.close()

sleep(1.0) continue

 Node Subscriber Pada Arduino /*

* rosserial Subscriber Example * Blinks an LED on callback */

#define USE_USBCON

#include <ros.h>

#include <std_msgs/Int32.h>

#define STEP_PIN1 5 // Connect the driver's step pin to pin 5

#define DIRECTION_PIN1 6 // Connect the driver's direction pin pin 6

#define STEP_PIN2 7 // Connect the driver's step pin to pin 5

#define DIRECTION_PIN2 8 // Connect the driver's direction pin pin 6

#define VRM1 22

#define CW1 23

#define RUN1 24

#define VRM2 26

#define CW2 27

#define RUN2 28

#define BERHENTI 0

#define MAJU 1

#define MUNDUR -1

#define MAJUKANAN 2

#define MAJUKIRI 3

#define MUNDURKANAN -2

#define MUNDURKIRI -3

#define PUTARKANAN 4

#define PUTARKIRI -4 int keadaan;

ros::NodeHandle nh;

void messageCallback(const std_msgs::Int32& cmd_msg) { int cmd = cmd_msg.data;

switch (cmd) {

case BERHENTI: keadaan = BERHENTI; berhenti(); break;

case MAJU: keadaan = MAJU; maju(); break;

case MUNDUR: keadaan = MUNDUR; mundur(); break;

case MAJUKANAN: keadaan = MAJUKANAN; maju(); break;

case MAJUKIRI: keadaan = MAJUKIRI; maju(); break;

case MUNDURKANAN: keadaan = MUNDURKANAN; mundur(); break;

case MUNDURKIRI: keadaan = MUNDURKIRI; mundur(); break;

case PUTARKANAN: keadaan = PUTARKANAN; belokKanan(); break;

case PUTARKIRI: keadaan = PUTARKIRI; belokKiri(); break;

default: break;

}

}

ros::Subscriber<std_msgs::Int32> sub("turtle_control", &messageCallback);

void setup() {

pinMode(LED_BUILTIN, OUTPUT);

nh.initNode();

nh.subscribe(sub);

pinMode(STEP_PIN1, OUTPUT);

pinMode(DIRECTION_PIN1, OUTPUT);

pinMode(STEP_PIN2, OUTPUT);

pinMode(DIRECTION_PIN2, OUTPUT);

pinMode(VRM1, OUTPUT);

pinMode(CW1 , OUTPUT);

pinMode(RUN1, OUTPUT);

pinMode(VRM2, OUTPUT);

pinMode(CW2 , OUTPUT);

pinMode(RUN2, OUTPUT);

keadaan = BERHENTI;

}

void belokKanan() {

delay(10);

digitalWrite(RUN2, LOW);

delay(10);

digitalWrite(CW2, LOW);

delay(10);

digitalWrite(RUN2, LOW);

digitalWrite(VRM2, LOW);

}

void belokKiri() {

delay(10);

digitalWrite(RUN2, LOW);

delay(10);

digitalWrite(CW2, LOW);

delay(10);

digitalWrite(RUN2, LOW);

digitalWrite(VRM2, LOW);

}

void berhenti() {

delay(10);

digitalWrite(RUN2, LOW);

delay(10);

digitalWrite(CW2, LOW);

delay(10);

digitalWrite(RUN2, LOW);

digitalWrite(VRM2, LOW);

}

void maju() {

delay(10);

digitalWrite(RUN2, HIGH);

delay(10);

digitalWrite(CW2, HIGH);

delay(10);

digitalWrite(RUN2, LOW);

digitalWrite(VRM2, HIGH);

}

void mundur() {

delay(10);

digitalWrite(RUN2, HIGH);

delay(10);

digitalWrite(CW2, LOW);

delay(10);

digitalWrite(RUN2, LOW);

digitalWrite(VRM2, HIGH);

}

void loop() {

switch (keadaan) { case BERHENTI:

break;

case MAJU:

MoveStepsKanan(4, 1000);

MoveStepsKiri(-4, 1000);

break;

case MUNDUR:

MoveStepsKanan(-4, 1000);

MoveStepsKiri(4, 1000);

break;

case MAJUKANAN:

MoveStepsKanan(4, 1000);

MoveStepsKiri(-8, 1000);

break;

case MAJUKIRI:

MoveStepsKanan(8, 1000);

MoveStepsKiri(-4, 1000);

break;

case MUNDURKANAN:

MoveStepsKanan(-4, 1000);

MoveStepsKiri(8, 1000);

break;

case MUNDURKIRI:

MoveStepsKanan(-8, 1000);

MoveStepsKiri(4, 1000);

break;

case PUTARKANAN:

MoveStepsKanan(-4, 1000);

MoveStepsKiri(-4, 1000);

break;

case PUTARKIRI:

MoveStepsKanan(4, 1000);

MoveStepsKiri(4, 1000);

break;

}

nh.spinOnce();

delay(1);

}

void MoveStepsKanan(int steps, unsigned int microsecondStepDelay) {

if (steps < 0){

digitalWrite(DIRECTION_PIN1, LOW); // Set counter-clockwise direction }else{

digitalWrite(DIRECTION_PIN1, HIGH); // Set clockwise direction }

// Moves desired number of steps

// Motor rotates one step when STEP_PIN changes from HIGH to LOW for(int i = 0; i < abs(steps); i++){

digitalWrite(STEP_PIN1, HIGH);

delayMicroseconds(microsecondStepDelay/2);

digitalWrite(STEP_PIN1, LOW);

delayMicroseconds(microsecondStepDelay/2);

} }

void MoveStepsKiri(int steps, unsigned int microsecondStepDelay) {

if (steps < 0){

digitalWrite(DIRECTION_PIN2, LOW); // Set counter-clockwise direction }else{

digitalWrite(DIRECTION_PIN2, HIGH); // Set clockwise direction }

// Moves desired number of steps

// Motor rotates one step when STEP_PIN changes from HIGH to LOW for(int i = 0; i < abs(steps); i++){

digitalWrite(STEP_PIN2, HIGH);

delayMicroseconds(microsecondStepDelay/2);

digitalWrite(STEP_PIN2, LOW);

delayMicroseconds(microsecondStepDelay/2);

} }

Dengan menggunakan Rosserial dapat membuat komunikasi yang lancar antara perangkat keras mikrokontroler dan sistem ROS, memungkinkan untuk mengendalikan dan memonitor robot atau sistem lain secara lebih terstruktur dan terintegrasi. Langkah awal untuk membuat komunikasi serial dengan menjalankan program serial_node atau node yang akan memfasilitasi untuk melakukan komunikasi serial yang ditampilkan Gambar 5.9.

Gambar 5.10 Program Serial Node

Dengan menjalakan kedua program maka akan muncul topik dengan nama turtle_control seperti yang ditampilkan pada Gambar 5.10 dimana subscribernya adalah program pada ardunino.

Gambar 5.11 Komunikasi Serial menggunakan Rosserial

Dokumen terkait