• Tidak ada hasil yang ditemukan

Perancangan Kontroler Game Mobile Menggunakan Gyroscope Dengan Algoritma Pid Dan Kalman Filtering Berbasis Arduino Nano Dan Unity

N/A
N/A
Protected

Academic year: 2017

Membagikan "Perancangan Kontroler Game Mobile Menggunakan Gyroscope Dengan Algoritma Pid Dan Kalman Filtering Berbasis Arduino Nano Dan Unity"

Copied!
21
0
0

Teks penuh

(1)

LISTING PROGRAM

1. Arduino

#include <Wire.h> #include <Kalman.h> #include <SoftwareSerial.h>

SoftwareSerial BTserial(10, 9); // RX | TX

#define RESTRICT_PITCH

Kalman kalmanX; Kalman kalmanY;

/* IMU Data */

double accX, accY, accZ; double gyroX, gyroY, gyroZ; int16_t tempRaw;

int erorr1,erorr,pidx1,pidx2,pidy1,pidy2,error,error1,lastE1,lastE,Kp,Kd,Ki;//PID double gyroXangle, gyroYangle; // menghitung angel dengan menggunakan gyro

double compAngleX, compAngleY; // Menghitung angel dengan menggunakan complement filter double kalAngleX, kalAngleY; // menghitung angel menggunakan Kalman filter

uint32_t timer;

uint8_t i2cData[14]; // Penampung data pada komunikasi I2C

// TODO: Make calibration routine

void setup() {

(2)

Serial.begin(115200); Wire.begin();

#if ARDUINO >= 157

Wire.setClock(400000UL); // Set frekuensi menjadi 400khz pada komunikasi I2C #else

TWBR = ((F_CPU / 400000UL) - 16) / 2; // Set frekuensi menjadi 400khz pada komunikasi I2C #endif

i2cData[0] = 7; // mengambil sampel 1000Hz - 8kHz/(7+1) = 1000Hz

i2cData[1] = 0x00; // mematikan FSYNC dan mengeset 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampel data

i2cData[2] = 0x00; // mengeset Gyro Full Scale dengan Range to ±250deg/s i2cData[3] = 0x00; // mengeset Accelerometer Full Scale dengan Range to ±2g while (i2cWrite(0x19, i2cData, 4, false)); // menulis empat register dengan 1 waktu

while (i2cWrite(0x6B, 0x01, true)); // PLL with X axis gyroscope reference and disable sleep mode

while (i2cRead(0x75, i2cData, 1)); if (i2cData[0] != 0x68) {

Serial.print(F("Error reading sensor")); while (1);

}

delay(100);

/* mengambil kalman and gyro pada angle awal */ while (i2cRead(0x3B, i2cData, 6));

accX = (int16_t)((i2cData[0] << 8) | i2cData[1]); accY = (int16_t)((i2cData[2] << 8) | i2cData[3]); accZ = (int16_t)((i2cData[4] << 8) | i2cData[5]); // mengubah data radians menjadi degrees #ifdef RESTRICT_PITCH

double roll = atan2(accY, accZ) * RAD_TO_DEG;

(3)

#else // Eq. 28 and 29

double roll = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG; double pitch = atan2(-accX, accZ) * RAD_TO_DEG;

#endif

kalmanX.setAngle(roll); // mengeset angle awal kalmanY.setAngle(pitch);

gyroXangle = roll; gyroYangle = pitch; compAngleX = roll; compAngleY = pitch;

timer = micros(); }

void PIDX() {

pidx1=kalAngleX; error=0-pidx1;

pidx2=(Kp*error)+(Ki*(lastE+error))+(Kd*(error-lastE)); lastE=error;

}

void PIDY() {

pidy1=kalAngleY; error1=0-pidy1;

pidy2=(Kp*error1)+(Ki*(lastE1+error1))+(Kd*(error1-lastE1)); lastE1=error1;

}

void loop() {

/* Update all the values */

(4)

accX = (int16_t)((i2cData[0] << 8) | i2cData[1]); accY = (int16_t)((i2cData[2] << 8) | i2cData[3]); accZ = (int16_t)((i2cData[4] << 8) | i2cData[5]); tempRaw = (int16_t)((i2cData[6] << 8) | i2cData[7]); gyroX = (int16_t)((i2cData[8] << 8) | i2cData[9]); gyroY = (int16_t)((i2cData[10] << 8) | i2cData[11]); gyroZ = (int16_t)((i2cData[12] << 8) | i2cData[13]);;

double dt = (double)(micros() - timer) / 1000000; timer = micros();

// mengubah data radians menjadi degrees #ifdef RESTRICT_PITCH // Eq. 25 and 26

double roll = atan2(accY, accZ) * RAD_TO_DEG;

double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG; #else // Eq. 28 and 29

double roll = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG; double pitch = atan2(-accX, accZ) * RAD_TO_DEG;

#endif

double gyroXrate = gyroX / 131.0; // Convert to deg/s double gyroYrate = gyroY / 131.0; // Convert to deg/s

#ifdef RESTRICT_PITCH

//memperbaiki problem perpindahan ketika accelerometer sudut sekitar -180 dan 180 derajat if ((roll < -90 && kalAngleX > 90) || (roll > 90 && kalAngleX < -90)) {

kalmanX.setAngle(roll); compAngleX = roll; kalAngleX = roll; gyroXangle = roll; } else

(5)

if (abs(kalAngleX) > 90)

gyroYrate = -gyroYrate; // Membalikkan tingkat, sehingga cocok accelerometer membaca terbatas

kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt); #else

//memperbaiki problem perpindahan ketika accelerometer sudut sekitar -180 dan 180 derajat if ((pitch < -90 && kalAngleY > 90) || (pitch > 90 && kalAngleY < -90)) {

kalmanY.setAngle(pitch); compAngleY = pitch; kalAngleY = pitch; gyroYangle = pitch; } else

kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt); // menghitung sudut menggunakan Kalman filter

if (abs(kalAngleY) > 90)

gyroXrate = -gyroXrate; // Membalikkan tingkat, sehingga cocok accelerometer membaca terbatas

kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt); // menghitung sudut menggunakan Kalman filter

#endif

gyroXangle += gyroXrate * dt; // menghitung sudut gyro tanpa filter gyroYangle += gyroYrate * dt;

//gyroXangle += kalmanX.getRate() * dt; // menghitung sudut gyro menggunakan unbiased rate //gyroYangle += kalmanY.getRate() * dt;

compAngleX = 0.93 * (compAngleX + gyroXrate * dt) + 0.07 * roll; // menghitung sudut menggunakan Complimentary filter

compAngleY = 0.93 * (compAngleY + gyroYrate * dt) + 0.07 * pitch;

(6)

if (gyroXangle < -180 || gyroXangle > 180) gyroXangle = kalAngleX;

if (gyroYangle < -180 || gyroYangle > 180) gyroYangle = kalAngleY;

//pembacaan komunikasi serial if (BTserial.available())

{

Serial.write(BTserial.read()); }

if (kalAngleY >= 40) { BTserial.print("W\n"); delay(10);

}

if (kalAngleY <= -40) { BTserial.print("S\n"); delay(10);

}

if (kalAngleX >= 40 ) {

BTserial.print("D\n"); delay(10);

}

if (kalAngleX <= -40) { BTserial.print("A\n"); delay(10);

}

(7)

BTserial.print("\n"); delay(10);

}

/* Print Data */

#if 0 // Set to 1 to activate

Serial.print(accX); Serial.print("\t"); Serial.print(accY); Serial.print("\t"); Serial.print(accZ); Serial.print("\t");

Serial.print(gyroX); Serial.print("\t"); Serial.print(gyroY); Serial.print("\t"); Serial.print(gyroZ); Serial.print("\t");

Serial.print("\t"); #endif

#if 1

Serial.print(roll); Serial.print("\t"); Serial.print(gyroXangle); Serial.print("\t"); Serial.print(compAngleX); Serial.print("\t"); Serial.print(kalAngleX); Serial.print("\t");

Serial.print("\t");

Serial.print(pitch); Serial.print("\t"); Serial.print(gyroYangle); Serial.print("\t"); Serial.print(compAngleY); Serial.print("\t"); Serial.print(kalAngleY); Serial.print("\t"); #endif

#if 0 // Set to 1 to print the temperature Serial.print("\t");

(8)

Serial.print(temperature); Serial.print("\t"); #endif

Serial.print("\r\n");

delay(2); }

2. Unity

1.Untuk Komunikasi bluetooth

using UnityEngine;

using UnityEngine.SceneManagement; using UnityEngine.UI;

using System.Collections.Generic;

using leithidev.unityassets.nativebt.android.entities;

public class BTChat : MonoBehaviour {

public Text _connectedToText; public Text _listeningOnText; public Text _chatText;

public InputField _sendInputField; public Text _sendText;

public PairedDeviceButton _pairedDeviceListButton; public RectTransform _pairedDeviceList;

public RectTransform _btnDisconnect; public RectTransform _btnPairedDevices;

(9)

// Use this for initialization void Start()

{

NativeBTRuntime.NBTR.BTHandler.BTEventsHandler.BTMessageReceived += OnMessageReceived;

NativeBTRuntime.NBTR.BTHandler.BTEventsHandler.BTMessageSent += OnMessageSent; NativeBTRuntime.NBTR.BTHandler.BTEventsHandler.BTDeviceConnected +=

OnBtDeviceConnected;

NativeBTRuntime.NBTR.BTHandler.BTEventsHandler.BTDeviceDisconnected += OnBtDeviceDisconnected;

NativeBTRuntime.NBTR.BTHandler.BTEventsHandler.BTDeviceConnectingFailed += OnBTDeviceConnectingFailed;

this._pairedDeviceList.gameObject.SetActive(false); this._btnDisconnect.gameObject.SetActive(false); }

private void OnBTDeviceConnectingFailed(LWBluetoothDevice device) {

this._connectedToText.text = "Connecting to " + device.GetName() + " failed!"; }

private void OnBtDeviceConnected(LWBluetoothDevice device) {

this._connectedTo = device;

this._connectedToText.text = device.GetName(); this._btnDisconnect.gameObject.SetActive(true); this._btnPairedDevices.gameObject.SetActive(false); SceneManager.LoadScene (1);

}

private void OnBtDeviceDisconnected(LWBluetoothDevice device) {

(10)

this._connectedToText.text = "";

this._btnDisconnect.gameObject.SetActive(false); this._btnPairedDevices.gameObject.SetActive(true); }

private void OnMessageSent(string msg) {

this._chatText.text += "\n" + NativeBTRuntime.NBTR.BTWrapper.GetBTAdapter().GetName() + ": " + msg;

}

private void OnMessageReceived(string msg) {

//this._chatText.text += "\n" + this._connectedTo.GetName() + ": " + msg; }

public void OnDisconnectButtonClicked() {

NativeBTRuntime.NBTR.BTWrapper.Disconnect(); }

public void OnSendButtonClicked() {

string msg = this._sendInputField.text; this._sendInputField.text = "";

NativeBTRuntime.NBTR.BTWrapper.Send(msg + System.Environment.NewLine); }

(11)

NativeBTRuntime.NBTR.BTWrapper.Connect(btDevice, this.uuid); this._pairedDeviceList.gameObject.SetActive(false);

}

public void OnPairedDevicesClicked() {

if (!NativeBTRuntime.NBTR.BTWrapper.GetBTAdapter().IsEnabled()) {

NativeBTRuntime.NBTR.BTWrapper.ShowBTEnableRequest(); }

else {

IList<LWBluetoothDevice> devices =

NativeBTRuntime.NBTR.BTWrapper.GetPairedDevices(); this._pairedDeviceList.gameObject.SetActive(true); this.ClearPairedDevicesList();

if (devices.Count == 0) {

this._pairedDeviceList.gameObject.SetActive(false); }

foreach (LWBluetoothDevice device in devices) {

PairedDeviceButton pdb = Instantiate<PairedDeviceButton>(this._pairedDeviceListButton); pdb._device = device;

pdb.GetComponent<Button>().GetComponentInChildren<Text>().text = device.GetName() + "|" + device.GetAddress();

pdb.GetComponent<Button>().onClick.AddListener(() => OnPairedDeviceButtonClicked(pdb._device));

pdb.transform.SetParent(this._pairedDeviceList); }

(12)

private void ClearPairedDevicesList() {

IList<GameObject> objsToDestroy = new List<GameObject>(); for (int x = 0; x < this._pairedDeviceList.transform.childCount; x++) {

objsToDestroy.Add(this._pairedDeviceList.transform.GetChild(x).gameObject); }

foreach(GameObject go in objsToDestroy) {

Destroy(go); }

}

public void OnListenClicked() {

NativeBTRuntime.NBTR.BTWrapper.Disconnect();

if (!NativeBTRuntime.NBTR.BTWrapper.GetBTAdapter().IsEnabled()) {

NativeBTRuntime.NBTR.BTWrapper.ShowBTEnableRequest(); }

else {

NativeBTRuntime.NBTR.BTWrapper.Listen(true, this.uuid); this._listeningOnText.text = "Listen on: " + uuid;

} }

private LWBluetoothDevice _connectedTo; }

(13)

using UnityEngine;

public class UnityChanControlScriptWithRgidBody : MonoBehaviour { private CapsuleCollider col; private Rigidbody rb; private Vector3 velocity; private float orgColHight;

private Vector3 orgVectColCenter;

private Animator anim;

private AnimatorStateInfo currentBaseState; private GameObject cameraObject;

static int idleState = Animator.StringToHash("Base Layer.Idle");

static int locoState = Animator.StringToHash("Base Layer.Locomotion"); static int jumpState = Animator.StringToHash("Base Layer.Jump"); static int restState = Animator.StringToHash("Base Layer.Rest");

void Start ()

cameraObject = GameObject.FindWithTag("MainCamera"); orgColHight = col.height;

orgVectColCenter = col.center;

NativeBTRuntime.NBTR.BTHandler.BTEventsHandler.BTMessageReceived += OnMessageRece ived;

}

(14)

{

currentBaseState = anim.GetCurrentAnimatorStateInfo(0); rb.useGravity = true;

velocity = new Vector3(0, 0, v);

velocity = transform.TransformDirection(velocity); if (v > 0.1) {

transform.localPosition += velocity * Time.fixedDeltaTime;

transform.Rotate(0, h * rotateSpeed, 0);

if (currentBaseState.nameHash == locoState){

(15)

resetCollider(); }

}

(16)

}

4. Untuk Pergerakan Kamera

using UnityEngine; using System.Collections;

public class ThirdPersonCamera : MonoBehaviour {

(17)

}

void setCameraPositionNormalView() {

void setCameraPositionFrontView() {

void setCameraPositionJumpView() {

bQuickSwitch = false;

transform.position = Vector3.Lerp(transform.position, jumpPos.position, Time.fixedDeltaTi me * smooth);

transform.forward = Vector3.Lerp(transform.forward, jumpPos.forward, Time.fixedDeltaTim e * smooth);}

(18)

D

AFTAR

R

IWAYAT

H

IDUP

C

URRICULUM

V

ITAE

PERSONAL DATA

Full Name

: Bobby Putra Johan

Nick Name

: Bobby

Place/ Date of Birth

: Medan/April 20

rd

1994

Sex

: Male

Religion

: Islam

Nationality

: Indonesia

Address

: Perumnas Simalingkar, Kec, Pancur Batu

Mobile Phone

: 081361115937

E-mail

: bat_devil5@yahoo.com

Marital Status

: unmarried / married

EDUCATION

Bachelor of Computer Science

University of Sumatera Utara, Medan

2012-Present

Higher Secondary Education

SMK TELKOM SANDHY PUTRA

(19)

Secondary Education

SMPN 2 MEDAN

2005-2008

Primary Education

SDN 068008 MANGGA

1999-2005

Programming : C#, C

Database

: MySQL, Sqlite, Ms. Access

IDE

: Unity, Free Pascal, Dev C++, Arduino ,CV-Avr

Other

: -

Fire fighting Robot

Line Follower Robot

Automatic Locking System

COMPUTER SKILL

(20)

ORGANIZATIONAL EXPERIENCES

No

Organization

Position

Year

1

Sikonek (Sistem kontrol dan elektronika)

Anggota Humas

2013-2014

2

Sikonek (Sistem kontrol dan elektronika)

Koordinator

Litbang(penelitian

dan pengembangan)

2014-2015

3

IKLC USU

Koordinator

Organisasi dan

Arsitektur Komputer

2014-2015

SEMINARS

No. Seminar

Year

1

Si GELITIK

2013

4

SENARAI

2014

“I hereby declare that all information above is true and correct to the best of my knowledge.”

Medan,21 Juli 2017

(21)

DAFTAR PUSTAKA

Cotta, A. & Devidas, N. T. 2016. Wireless Communication Using HC-05 Bluetooth Module

Interfaced with Arduino.

International Journal of Science, Engineering and

Technology Research

(IJSETR) 5(4) : 869-872.

Kurniawan, T., Hanafi, L. & Apriliani, E. 2013. Penerapan Metode

Filter

Kalman dalam

Perbaikan Hasil Prediksi Cuaca dengan Metode ARIMA 1-7.

Kalane, P. & Loni, P. 2012. Target Tracking Using Kalman Filter. International Journal of

Science & Technology 2(2) : 17-24 (Online)

www.ijst.co.in

.

Quadri, S. A. & Sidek. O. 2014. Error and Noise Analysis in an IMU using Kalman Filter.

International Journal of Hybrid Information Technology

7(3) : 39-48 (Online)

http://dx.doi.org/10/14257/ijhit.2014.7.3.06

.

Fahmedha, N,. Prakash, P. C,. Pooja, A,. & Rachana, R. 2015. Estimation of System

Parameters Using Kalman Filter and Extended Kalman Filter.

International

Journal of Advanced Technology and Engineering Exploration

2(6): 84-89.

Sierociuk, D. & Dzielinski, A. 2006. Farctional Kalman Filter Algorithm for The State,

Parameters and Order of Fractional System Estimation.

International Journal of

Applications Math and Computer Science

16(1): 129-140.

Bassi, S.J,. Mishra, M.K,. & Omizegba, E.E. 2011. Automatic Tuning of

Proportional-Integral-Derivative (PID) Controller using Particle Swarm Optimization (PSO)

Algorithm.

International Journal of Artificial Intelligence & Applications

(IJAIA)

2(4) : 25-34 (Online) DOI:10.5121/ijaia.2011.2403.

Mon, Y. 2015. The Gyroscope Senssor Test by Using Arduino Platform.

International

Journal of Sciencetific and Technology Research

(IJSTR) 4(6): 398-400 (Online)

Referensi

Dokumen terkait

Hasil penelitian ini dapat menjadikan model pembelajaran kooperatif tipe TAI dengan pendekatan open ended, sebagai salah satu model alternatif yang dapat diaplikasikan dalam

Berdasarkan penelitian yang dilakukan di RSUD Ratu Zalecha Martapura tentang KLB DBD di RSUD Ratu Zalecha adalah sebagai berikut : Analisa data yang telah dilakukan

a) Timbang kaleng yang masih utuh, buka dan tuang seluruh isinya ke dalam ayakan No 8. Dengan hati-hati menggunakan tangan balikkan buah yang memiliki cekungan bila

Judi atau permainan “judi” atau “perjudian” menurut Kamus besar Bahasa Indonesia adalah “Permainan dengan memakai uang sebagai taruhan” Perjudian diartikan

pada periode tahun status. 6) Variabel SETA secara konsisten memiliki tanda koefisien regresi yang positif dengan nilai probabilitas (Sig) yang lebih besar dari

Pengambilan keputusan pembelian juga merupakan suatu proses psikologis yang dilalui oleh konsumen, menurut Djatnika (2007) prosesnya pengambilan keputusan diawali dengan

Deflasi terjadi karena adanya penurunan harga-harga yang ditunjukkan oleh penurunan indeks beberapa kelompok pengeluaran, yaitu kelompok bahan makanan 0,88 persen dan