Telemetrinin Robot İçerisindeki Veri Günlüklerinde Saklanması

Varsayılan olarak hiçbir telemetri verisi robot içerisinde kaydedilmemektedir. DataLogManager sınıfı, daha düşük düzeydeki telemetri verilerinin robot içerisindeki veri günlüğünde saklanması adına DataLog sınıfı için elverişli bir sarıcı sağlamaktadır. WPILib veri günlükleri boyut ve hız sebeplerinden ötürü binom şeklindedir. Genellikle WPILib tarafından sağlanan veri günlüğü kolaylıkları robot kodu üzerine az miktarda ek yük bindirmektedir. Bunun sebebi tüm dosya Giridi-Çıktıları ayrı bir iş parçacığında gerçekleştirilmesi yüzünden kayıt işleminin birçok mutex - karşılıklı dışlama edinimi ve veri kopyalamasından oluşmasıdır

Veri Günlüklerinin Yapısı

NetworkTables’a benzer bir şekilde veri günlükleri de özel bir veri türüne sahip dizgi tanıtıcılara (anahtarlara) sahip girişler kavramına sahiptir. NetworkTables’ın aksine veri türünün girişi gerçekleştirildikten sonra veri türü değiştirilmez ve girişler üstverilere de sahiptir. Rastgele (ancak genelde JSON) bir dizi girişiyle ilgili veri kaynağı veya veri şeması gibi ek bilgilerin görüntülenebilmektedir. Ayrıca NetworkTables’ın aksine veri kayıt işlemi tek yönlüdür: DataLog sınıfı yalnızca veri günlükleri yazabilir (yazılan değerlerin yeniden okunmasını desteklememektedir), DataLogReader sınıfı yalnızca veri günlüklerini okuyabilir (veri günlüğündeki verilerin değiştirilmesini desteklememektedir).

Veri günlükleri bir dizi zaman bilgisine sahip kayıtlardan oluşmaktadır. Kontrol kayıtları girişlere dair üstverilerin başlatılması, sonlandırılması veya değiştirilmesine olanak tanımaktadır ve veri günlükleri, veri değerlerinde yapılan değişiklikleri kaydetmektedir. Zaman bilgileri tamsayı olan mikro saniye cinsinde saklanmaktadır, günlükler RoboRIO’da çalıştırılırken (Timer.getFPGATimestamp() tarafıdan döndürülen zaman bilgisiyle aynı) FPGA zaman bilgisi kullanılmaktadır.

Not

For more information on the details of the data log file format, see the WPILib Data Log File Format Specification.

DataLogManager ile Standart Veri Kaydı

The DataLogManager class (Java, C++, Python) provides a centralized data log that provides automatic data log file management. It automatically cleans up old files when disk space is low and renames the file based either on current date/time or (if available) competition match number. The data file will be saved to a USB flash drive in a folder called logs if one is attached, or to /home/lvuser/logs otherwise.

Not

USB flaş bellekleri roboRIO ile çalışabilmeleri için FAT32 şeklinde biçimlendirilmelidir. NTFS veya exFAT şeklinde biçimlendirilmiş bellekler çalışmayacaktır. Windows, 32GB üstündeki bellekleri FAT32 ile biçimlendirmediği için 32GB ve altında depolama alanına sahip bellekler tavsiye edilmektedir.

Kayıt dosyaları DS bağalanana kadar başta FRC_TBD_{random}.wpilog şeklinde adlandırılmaktadır. DS bağlandıktan sonra kayıt dosyası (tarih/saatin UTC olduğu) FRC_yyyyMMdd_HHmmss.wpilog şeklinde yeniden adlandırılmaktadır. FMS bağlı ve bir müsabaka numarası sağlıyorsa, kayıt dosyası FRC_yyyyMMdd_HHmmss_{etkinlik}_{müsabaka}.wpilog şeklinde yeniden adlandırılmaktadır.

Başlatılma sırasında bir DS’in bağlanmadığı varolan tüm kayıt dosyaları silinecektir. Hedef depolama alanında 50 MB’dan az boş alan bulunuyorsa, FRC_ kayıt dosyaları (eskiden yeniye olacak şekilde) 50 MB boş alan VEYA 10 tane dosya geriye kalana kadar silinecektir.

DataLogManager’ın en temel kullanımı yalnızca tek bir kod satırı gerektirmektedir (normalde bu satır Robot constructor’ı tarafından çağırılmaktadır). Bu işlem tüm NetworkTables değişikliklerini veri günlüğüne kaydedecektir.

import edu.wpi.first.wpilibj.DataLogManager;
// Starts recording to data log
DataLogManager.start();
#include "frc/DataLogManager.h"
// Starts recording to data log
frc::DataLogManager::Start();
from wpilib import DataLogManager
DataLogManager.start()

DataLogManager, mesajlaşmaların veri günlüğüne messages girişi altında kaydedilmesine olanak tanıyan bir kolaylık işlevi (DataLogManager.log()) sağlamaktadır. Ayrıca mesajın standart çıkışa çıktısı alınmaktadır, yani bu fonksiyon System.out.println()’in yerine geçebilmektedir.

DataLogManager aynı zamanda (UTC olarak) anlık roboRIO sistem zamanını her ~5 saniyede bir veri günlüğündeki systemTime girişine kaydetmektedir. Bu kayıt veri günlüğünü (kabaca) DS günlükleri veya müsabaka videosu gibi diğer kayıtlarla senkronize etmek için kullanılabilmektedir.

Özel veri kaydı için yönetilen DataLog’a DataLogManager.getLog() ile erişilebilmektedir.

Kumanda Kolu Verilerinin Kaydı

DataLogManager varsayılan olarak kumanda kolu verilerini kaydetmemektedir. DriverStation sınıfı, DS kontrol ve kumanda kolu verilerinin startDataLog() işlevi üzerinden kaydedilmesini desteklemektedir:

import edu.wpi.first.wpilibj.DataLogManager;
import edu.wpi.first.wpilibj.DriverStation;
// Starts recording to data log
DataLogManager.start();
// Record both DS control and joystick data
DriverStation.startDataLog(DataLogManager.getLog());
// (alternatively) Record only DS control data
DriverStation.startDataLog(DataLogManager.getLog(), false);
#include "frc/DataLogManager.h"
#include "frc/DriverStation.h"
// Starts recording to data log
frc::DataLogManager::Start();
// Record both DS control and joystick data
DriverStation::StartDataLog(DataLogManager::GetLog());
// (alternatively) Record only DS control data
DriverStation::StartDataLog(DataLogManager::GetLog(), false);
from wpilib import DataLogManager, DriverStation
# Starts recording to data log
DataLogManager.start()
# Record both DS control and joystick data
DriverStation.startDataLog(DataLogManager.getLog())
# (alternatively) Record only DS control data
DriverStation.startDataLog(DataLogManager.getLog(), False)

DataLog ile Özel Veri Kaydı

The DataLog class (Java, C++, Python) and its associated LogEntry classes (e.g. BooleanLogEntry, DoubleLogEntry, etc) provides low-level access for writing data logs.

Not

Bu durumda NetworkTables’ın aksine herhangi bir değişiklik kontrolü yapılmamaktadır. LogEntry.append() işlevine yapılan her bir çağrı veri günlüğüne bir kaydın yapılmasıyla sonuçlanacaktır. Değişiklikleri kontrol etmek ve günlüğe sadece gerektiği takdirde eklemeler yapmak, çağırıyı yapan kişinin sorumluluğudur.

Değerlerin NetworkTables yerine sadece bir veri günlüğüne kaydedilmesini sağlamak için LogEntry sınıfları DataLogManager ile birlikte kullanılabilmektedir:

import edu.wpi.first.util.datalog.BooleanLogEntry;
import edu.wpi.first.util.datalog.DataLog;
import edu.wpi.first.util.datalog.DoubleLogEntry;
import edu.wpi.first.util.datalog.StringLogEntry;
import edu.wpi.first.wpilibj.DataLogManager;
BooleanLogEntry myBooleanLog;
DoubleLogEntry myDoubleLog;
StringLogEntry myStringLog;

public Robot() {
  // Starts recording to data log
  DataLogManager.start();
  // Set up custom log entries
  DataLog log = DataLogManager.getLog();
  myBooleanLog = new BooleanLogEntry(log, "/my/boolean");
  myDoubleLog = new DoubleLogEntry(log, "/my/double");
  myStringLog = new StringLogEntry(log, "/my/string");
}
public void teleopPeriodic() {
  if (...) {
    // Only log when necessary
    myBooleanLog.append(true);
    myDoubleLog.append(3.5);
    myStringLog.append("wow!");
  }
}
#include "frc/DataLogManager.h"
#include "wpi/DataLog.h"
wpi::log::BooleanLogEntry myBooleanLog;
wpi::log::DoubleLogEntry myDoubleLog;
wpi::log::StringLogEntry myStringLog;
Robot() {
  // Starts recording to data log
  frc::DataLogManager::Start();
  // Set up custom log entries
  wpi::log::DataLog& log = frc::DataLogManager::GetLog();
  myBooleanLog = wpi::log::BooleanLogEntry(log, "/my/boolean");
  myDoubleLog = wpi::log::DoubleLogEntry(log, "/my/double");
  myStringLog = wpi::log::StringLogEntry(log, "/my/string");
}
void TeleopPeriodic() {
  if (...) {
    // Only log when necessary
    myBooleanLog.Append(true);
    myDoubleLog.Append(3.5);
    myStringLog.Append("wow!");
  }
}
 from wpilib import DataLogManager, TimedRobot
 from wpiutil.log import (
     DataLog,
     BooleanLogEntry,
     DoubleLogEntry,
     StringLogEntry,
 )
class MyRobot(TimedRobot):
     def robotInit(self):
         # Starts recording to data log
         DataLogManager.start()
         # Set up custom log entries
         log = DataLogManager.getLog()
         self.myBooleanLog = BooleanLogEntry(log, "/my/boolean")
         self.myDoubleLog = DoubleLogEntry(log, "/my/double")
         self.myStringLog = StringLogEntry(log, "/my/string")
     def teleopPeriodic(self):
         if ...:
             # Only log when necessary
             self.myBooleanLog.append(True)
             self.myDoubleLog.append(3.5)
             self.myStringLog.append("wow!")