0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ROS2講座08 SQLite基礎

Last updated at Posted at 2023-07-13

環境

この記事は以下の環境で動いています。

項目
CPU Core i5-8250U
Ubuntu 22.04
ROS2 Humble
SQLite 3.37.2

概要

ROS2はパラメーター等データの読み取りは仕組みがあるのですが、不揮発にデータを保存する標準的な仕組みはありません。
ROS2の多くのノード(例:slamのmap情報の保存)ではファイル書き出しをして行っています。しかしプランニングのユーザーデータなど細々した情報が多く、それぞれをファイル書き出しすると管理が大変です。
ここではSQLiteのデータベースを使ってROS2実行中の情報を不揮発に保存することを目指します。sqliteはROS2のrosbagのファイル形式としても使われている形式です。

SQLite

データベースというとサーバーで動く物を想像しますが、SQLiteはローカルで動くデータベースで、ライブラリの形で提供されます。SQL構文でデータの操作を行うことが出来ます。

SQLiteをコマンドで使う

SQliteファイルを作る。

sqlite3をインストールします。

sqlite3のインストール
sudo apt install sqlite3

sqliteを実行することで

sqlite基本
$ sqlite3 data.db
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> # <- SQLのコマンドを打てる。Ctrl+Dで抜ける
$ ls
data.db
  • sqlite3コマンドの引数でファイルを指定します。存在しない場合はファイルを生成します。
  • sqlite>というプロンプトが出るのでここでSQLコマンドを打ち込みます。Ctrl+Dで抜けます。

table作成、行の挿入、内容の確認

データ操作
sqlite> CREATE TABLE DataList (name, count);sqlite> INSERT INTO DataList VALUES("hoge",10);

sqlite> SELECT * FROM DataList;
hoge|10

sqlite> INSERT INTO DataList VALUES("fuga",20);

sqlite> SELECT * FROM DataList;
hoge|10
fuga|20
  • RDBとは、簡単にいえばExcelのような表形式のデータをコマンドで扱えるものです。
  • CREATE TABLEで新たな表を作れます。かっこの中は列の設定です。多くのSQLデータベースでは型の指定が必須ですが、SQLiteでは型名の指定は不要です。
  • INSERT INTOではデータの行を追加します。
  • SELECTではデータの中身を見ることが出来ます。

SQLiteをsqlitebrowserで使う

sqlite3コマンドだけでデータを操作するのはつらいところ、sqlitebrowserを使うとGUIで操作が出来ます。

sqlitebrowserのインストール
sudo apt install sqlitebrowser 
sqlitebrowserの実行
sqlitebrowser 

「Open DataBase」のボタンで先ほどの「data.db」ファイルを選択します。
するとファイルの中身が表示して「Brows Data」タブを開くとデータベースが表示されます。

sqlitebrowser.png

GUI上の表に入力することで、データを変更することもできます。データは「Write Change」ボタンを押したときにファイルに書き込まれます。

SQLiteをc++から使う

ソースコード

sqlite_lecture/src/sample1/main.cpp
#include <sqlite3.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
  sqlite3 *db = NULL;
  if (sqlite3_open("data.db", &db) != SQLITE_OK)
  {
    printf("%s[%s]\n", __func__, sqlite3_errmsg(db));
    return -1;
  }

  if (sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS CountList (name PRIMARY KEY, count);", NULL, NULL, NULL) != SQLITE_OK){
    printf("%s[%s]\n", __func__, sqlite3_errmsg(db));
    return -1;
  }

  if (sqlite3_exec(db, "INSERT OR IGNORE INTO CountList VALUES ('boot', 0);", NULL, NULL, NULL) != SQLITE_OK){
    printf("%s[%s]\n", __func__, sqlite3_errmsg(db));
    return -1;
  }

  if (sqlite3_exec(db, "UPDATE CountList SET count = count + 1 WHERE name == 'boot'", NULL, NULL, NULL) != SQLITE_OK){
    printf("%s[%s]\n", __func__, sqlite3_errmsg(db));
    return -1;
  }

  printf("Done\n");
  return 0;
}
  • CREATE TABLEでテーブルを作成します。
    • IF NOT EXISTSはテーブルが無い時だけ作成します。これをつけないと、テーブルがあるときにエラーになります。
    • PRIMARY KEYはその行の値がユニークになる制約を加えます。
  • INSERT INTOはテーブルにレコード(行)を追加します。
    • これだけだとPRIMARY KEYの制約があるために2回目以降の実行でエラーになってしまいます。OR IGNOREをつけるとPRIMARY KEYの制約に反する時は無視します。
  • UPDATEコマンドではname = boolのレコードでcountをインクリメントします。

ビルド&実行

ビルド
source /opt/ros/humble/setup.bash
cd ros2_ws
colcon build
実行
$ ros2 run sqlite_lecture sample1
Done
$ ros2 run sqlite_lecture sample1
Done
$ ros2 run sqlite_lecture sample1
Done
$ sqlite3 data.db 
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> SELECT * FROM CountList;
boot|3

3回実行すると、bootの値は3になります。

目次ページへのリンク

ROS2講座の目次へのリンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?