KRPC İle Raspberry Pi-Kerbal Space Program Entegrasyonu

Bu yazımda Kerbal Space Program‘a Python ile roket kontrol yazılımı geliştirmeyi ve bu yazılımı elektronik ile birleştirerek nasıl kullanabileceğinizi anlatıyorum.

Kerbal Space Program Nedir?

Gerçekçi fizik ve aerodinamiklere sahip uzay simülasyon oyunu diyebiliriz. Oyunda Kerbal adı verilen bir uzaylı ırkının uzay programını yönetmekteyiz. Kısaca amacımız belirlediğimiz (veya atanan görev gereği) hedefe ulaşmak için çeşitli parçaları kullanarak uydular, roketler, roverlar ve benzeri araçlar yapmak. Bu araçların kontrolü normalde sadece oyuncudadır, fakat oyuna eklenen modlarla birlikte bu kalıbın dışına çıkabilmekteyiz.

KRPC Modu ve Kurulumu

Bu iş için kullanacağımız mod ise KRPC modu. Bu mod sayesinde çeşitli programlama dillerinde (C#, Python, Php, C++, Java, Lua) oyuna yazılım geliştirebiliriz. SpaceDock üzerinden modu indirdikten sonra KSP’nin dosya konumundan GameData içerisine girin sonra indirdiğiniz mod dosyasının içerisinden GameData altındaki dosyaları KSP de bulunan GameData klasörünün içine kopyalayın. Bu sayede mod kurulmuş olacaktır.

KRPC Server’ın Ayarlanması

Modu kurduktan sonra oyunu açın ve son kaydınıza girin. Ekranın sağ alt köşesinde KRPC paneli görünecektir. Default Server adında bir seçenek varsayılan olarak gelebilir, yoksa Add Server butonuna basılarak yeni bir sunucu ekleyin. Sonrasında sunucunun düzenlemek için Edit butonuna tıklayın. Sırasıyla protokolü TCP, erişim adresini Any yapın portları düzenlememize gerek yok (varsayılan olarak RPC_SERVER:50000-STREAM_SERVER:50001). Ardından Show Advanced Settings‘i açın ve Auto-Accept New Clients seçeneğini aktif edin. Son olarak ise Start‘a basarak sunucuyu başlatın.

KRPC Panel

KRPC Modülünün Pythona Kurulması

pip install krpc

Sonrasında modülün testini yapmak için modülü interaktif terminalde import edin.

import krpc

Programın Hazırlanması

Kendinize bir çalışma alanı açın ve içerisine py uzantılı kod dosyasını oluşturun. Bağlantının sınanması için bu kodları kullanabilirsiniz:

import krpc
conn = krpc.connect(name = 'Client1', address = '127.0.0.1', rpc_port = 50000, stream_port = 50001)
print(conn.krpc.get_status().version)

Yukarıdaki kod çalıştırıldığında KRPC sunucusuna Client1 ismiyle bağlanacak, sürüm bilgilerini alıp çıkış yapacaktır. Bağlantı başarısız olursa hata dönecektir. Adres kısmına şimdilik makinenin loopback adresini girebiliriz, raspberry ile çalışırken o kısma sunucunun çalıştığı adresi gireceğiz.

İlk Deneme

Roketin Tasarımı

Basit bir roket tasarımı yapalım. MK1 COMMAND POD üzerine bir adet paraşüt koyun. İtici olarak RT-5 SOLID FUEL BOOSTER kullanacağız. Kanatçıklar şimdilik çok önemli değil, isterseniz ekleyebilirsiniz.

Alçak irtifa bir uçuş olacağından fazla kompleks bir tasarıma ihtiyacımız yok.

Kontrol Programının Hazırlanması

Görev ve Plan

Roket kontrol programını kodlamadan önce kabaca bir plan yapalım. Öncelikle görevimiz kapsülün içerisindeki personelle birlikte roketi yakıtı bitene kadar ateşleyerek yörünge altı bir yüksekliğe çıkarmak, kabaca böyle tarif edebiliriz.

Şimdi biraz detaylandıralım. Roket 3.1m uzunluğunda ve 2.3m genişliğinde, 2530KG ağırlığında. Kapsülü iticiden ayıran bir ayraç olmadığından tek aşamalı bir görev olacak. Katı yakıtlı iticimize ise bir kere ateşledikten sonra müdahale edemiyoruz.

Şimdi işin matematiğini yapalım. Önce TWR nedir?

TWR bir aracın motorlarının gücünü kendi ağırlığına göre tanımlayan bir orandır yani İtiş Ağırlık Oranını hesaplamak için şu formülü kullanabiliriz:

TWR
  • Ft -> Motorların itme gücü.
  • m -> Roketin toplam ağırlığı.
  • g -> Yerel yerçekimi ivmesi.

Buna göre hesap yaparsak yaklaşık olarak 6.5 çıkmaktadır.

Kerbine göre TWR

6.5 değeri çok yüksek bir değer, bu değere bakarak aracımızın çok hızlı bir şekilde ivmeleneceğini tahmin edebiliriz. Bu arada hesaba katmadığımız bir diğer faktör ise aracımızın yükseldikçe yerçekimi ivmesinden kaçması. Yukarıdaki formül ile anlık bir hesap yaptık, doğru sonucu almak için bu işlemi birim zamanda yapmamız gerekmektedir. Fakat şuanda bu kadarı yeterli, basit bir proje yapıyoruz teorik kısımlarıyla fazla uğraşmaya gerek yok. Amaa…

DeltaV. DeltaV önemlidir bahsetmeden geçemem. Hızın birim zamanda değişimine DeltaV denir. Uzay araçlarının iticileri yakıtlarını bir süre içinde yakarlar. Bu süre içerisinde alabilecekleri toplam hız miktarı önemlidir. Misal Mun’a gitmek için yaklaşık 5000dV gereklidir, 5000dv’den daha düşük bir dv ile Mun’a gidemezsiniz.

DeltaV

Burda Isp motorun ne kadar verimlilik ile kullanıldığıdır. Mtotal iticinin toplam ağırlığı. Mtotal-Mfuel ise iticiden yakıtın kütlesi çıkarıldığında bulunan değerdir. Bu değere aynı zamanda Mdry da denmektedir. Mdry değerini bulduktan sonra paraşüt, kanatçık veya roketin üzerinde bulunan diğer parçaların ağırlıklarını da üstüne ekleyin.

Parçalarla ilgili çeşitli bilgileri KSP’nin Wiki sayfasından öğrenebilirsiniz. Eldeki değerleri formüle koyarak DeltaV hesabını yaparsak yaklaşık 745.87 değerini buluruz.

FR DV

Taslak

TWR, DeltaV gibi değerleri hesapladıktan sonra şimdi operasyonun nasıl gerçekleşeceğini simüle edelim. RT-5 iticimizin üzerinde 140 birimlik bir kayı yakıt var, iticinin saniyede 15.82 birim yakıt yaktığını biliyoruz. 140/15.82=8.849557522123893, yani 8.85 saniyelik bir ateşlemeden söz ediyoruz. RT-5 iticisi 8.85 saniyelik bir ateşlemede 6.56TWR ile 745.87DV harcayacak ve roket ivmenin de etkisiyle yaklaşık olarak 14000m kadar bir yüksekliğe ulaşacaktır.

Taslak

Roket kalkışını S noktasından yapacak. A noktasında roket yaklaşık olarak 6000m irtifada olacaktır, B noktasında ise roket tepe noktasına ulaşmış olacaktır. Roket C noktasına ulaştığında ise paraşütü açılacaktır. Son olarak L noktasına iniş yapacak.

Roket yaklaşık 2000m irtifaya ulaştığında yakıtının biteceğini tahmin ediyorum. Sonrasında roketi B noktasına sahip olduğu hızı götürecektir.

Yazılımın Hazırlanması

Bu kısımda Python ile roketin kontrol yazılımını hazırlayacağız. Düşünelim, roket kalkış yapmadan önce stabilizasyon sistemini açıp son kontrolleri yapacağız. Sonrasında itici ateşlenecek ve B noktasına kadar roket ulaşacak. İrtifa kaybetmeye başladıktan sonra roket 6000m irtifaya ulaştığında paraşüt açılacak ve iniş yapacak. Bu fikrimizi kabaca kodlayalaım.

import krpc
from os import system
from time import sleep
FL1 = False
FL2 = False
ALT = 6000
 # Paraşütün açılacağı yükseklik

conn = krpc.connect(name="FRC-C")
 # KRPC Bağlantı
ves = conn.space_center.active_vessel
 # Aktif aracın seçilmesi

print("[CONTROL] OPERATION STARTED")
sleep(1.34)
ves.control.throttle = 0.5
 # Motorun itiş gücü (min 0 max 1)
ves.control.sas = True
 # Stabilizasyon
if ves.control.sas:
    print("[CONTROL] SAS ACTIVATED")
sleep(0.5)
ves.control.activate_next_stage()
 # Diğer aşamaya geçiş (ateşleme)

while ves.flight().mean_altitude < ALT:
 # mean_altitude deniz seviyesinde yükseklik değeri
    FL1 = True
    print("[CONTROL] ALTITUDE {:.2f}".format(ves.flight().mean_altitude))
    if ves.flight().mean_altitude > ALT and FL1:
        print("[CONTROL] FL1 TRUE")        
        break
while ves.flight().mean_altitude > ALT and not FL2:
    print("[CONTROL] ALTITUDE ({:.2f}) GTH {} FL1 TRUE".format(ves.flight().mean_altitude, ALT))
    while ves.flight().mean_altitude < ALT and FL1:
        ves.control.activate_next_stage()
        FL2 = True
        print(f"[CONTROL] ALTITUDE LTH {ALT} FL1 TRUE FL2 TRUE")        
        break
while ves.flight().surface_altitude > 0:
 # Kara seviyesinde yükseklik değeri
    print("[CONTROL] ALTITUDE {:.2f}".format(ves.flight().surface_altitude))
    if ves.flight().surface_altitude <= 2:
        print("[CONTROL] OPERATION FINISHED")
        break

Kodu açıklamam gerekirse. KRPC ile bağlantıyı kuruyoruz FL1-2 adlı iki adet bool değişken oluşturuyoruz. FL1 roket 6000 metreyi geçtikten sonra True olmaktadır, FL2 ise roket 14000 metreden düşerken 6000 metreye indiğinde True olur. FL1-2 True ise ve roket 6000m’nin altındaysa paraşüt açılır. Roket 2m’nin (roketin uzunluğu) altına inene kadar kodlar çalışmaya devam eder. KRPC API komutlarının açıklamalarını kodda yorum satırı olarak belirttim.

FRC-C

Raspberry Pi İle KRPC Modülünün Kullanımı

Geniş modül desteği sayesinde şuana kadarki bütün işleri Pythonla hallettik. İşleri biraz ilerletip bu çalışmayı ilginç bir projeye çevirebiliriz, öyle de yapacağız. RasPi’nin GPIO pinleri sayesinde çeşitli elektronik bileşenlerini yazılımlarımızda kullanabilmekteyiz. RaspPi debian tabanlı bir linux işletim sistemine sahip ve python varsayılan olarak gelmekte. RasPi üzerindeki GPIO pinlerine erişmenin çeşitli yöntemleri olabilir, biz bu iş için Pythonı tercih edeceğiz. RasPiyi ağa bağlamayı unutmayın.

Varsayılan olarak gelen RPI.GPIO modülü sayesinde GPIO pinlerine erişim sağlaya bilmekteyiz. KRPC modülünü RaspPiye de kurduktan sonra KRPC ve RPI.GPIO kütüphanelerini import ederek sınayın. GPIO hakkında detaylı bilgi.

Sonrasında KRPC’nin sunucuya bağlanıp bağlanmadığını deneyin. Örnek olarak bu kod bağlantıyı test etmekte kullanılabilir:

import krpc
conn = krpc.connect(name = 'Client1', address = '192.168.1.7', rpc_port = 50000, stream_port = 50001) # Address parametresine Loopback adresinden farklı olarak bu sefer sunucu bilgisayarın ağdaki ip adresini girelim
print(conn.krpc.get_status().version)

Bağlantı kurulduysa GPIO pinlerini deneyelim.

Raspberry Pi GPIO Pinleri

Bu projede bir adet 3 ayaklı toggle anahtar kullandım. Anahtarın ilk ayağına 3.3v ortadaki ayağına 11.Pin(GPIO17) ve son ayağına ise GND bağlayın. Donanım kısmı bu kadar şimdi yazılım işini halledelim.

KRPC – RPI.GPIO

import RPi.GPIO as gpio
import time
import krpc

gpio.setmode(gpio.BCM)
p = 17
 # pin numarası
gpio.setup(p, gpio.IN) # 11.pin üzerinden input olacağını belirtiyoruz

con = krpc.connect(address='192.168.1.7', rpc_port=50000, stream_port=50001) # bağlantı
ves = con.space_center.active_vessel

while True:
        k = gpio.input(p)
        print(k)
        time.sleep(0.5)
        if gpio.input(p) == 1:
                time.sleep(0.5)
                if gpio.input(p) == 1:
                        time.sleep(0.25)
                        if gpio.input(p) == 1:
                                print(gpio.input(p))
                                ves.control.activate_next_stage()

Kod çalıştığında anahtar kapalıysa devamlı olarak ‘0‘ çıktısı alacaksınız. Eğer anahtar kapalı konuma gelirse 1.25 saniye sonra ‘1‘ çıktısı alırsınız sonra RasPi roketin kalkışı için sinyali gönderir. Bağlantıları anahtara lehimlemediğimden dolayı anahtar arada sırada kapalı duruma geçebiliyordu. Bu sıkıntı için yazılım tarafında iç içe IF kullanarak önlem aldım. Şöyle ki, ‘önce yarım saniye bekle sonra eğer anahtar kapalıysa (yani 1 ise) yarım saniye daha bekle tekrardan anahtarın kapalı olup olmadığını kontrol et, eğer kapalıysa çeyrek saniye daha bekle son olarak anahtar yine kapalıysa sinyali gönder‘ anlamında.

KRPC-RPI.GPIO

Ve bu yazıda böyle bitti. Şuana kadar anlattıklarımla çeşitli projeler oluşturabilirsiniz. Mesela Amatör roketiniz var ve manuel bir kontrol sistemi hazırlamak istiyorsunuz. Bu sistemin testini KSP üzerinde bu şekilde yapabilirsiniz, maliyetten ve zamandan tasarruf etmiş olursunuz.

suhaarslan

Posts created 14

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top