Extreme Data Logger : 都市と自然の記憶

というわけで、展覧会直前のドタバタで更新頻度が落ちてしまいましたが、Winter Change 2021 として開催した、「Extreme Data Logger : 都市と自然の記憶」が無事に開催されました。このブログでも登場していた除雪彫刻なども無事に展示することができました。

ひとまず写真で振り返っておきたいと思います。

 

作品、というよりは、リサーチの結果、プロトタイプ、試作、習作、実験といったようなものと、プロジェクト自体の紹介がメインでしたが、それでもメンバー自身としても見応えのあるものも出来上がったかなというところでした。反省点も色々あるので、来年度につながるよう、メンバーで共有していきたいと思います。

制作に関わったメンバーで、展覧会ツアーをした動画ありますので、合わせてご覧いただければと思います。

 

スノーシューとGPSロガーで描くモエレの雪上絵ワークショップ、当日。

本日は「スノーシューとGPSロガーで描くモエレの雪上絵」ワークショップ当日でした。

1月早々の大寒波のおかげで札幌でも例年にないくらい冷え込む日が続いていましたが、今日はワークショップ日和の晴れ。
三連休の開始ということもあり、公園内ではクロスカントリーの練習をする方や、モエレ山でそり遊びでにぎわっています。

ワークショップの午前の部はガラスのピラミッドスペース1でGPSロガーづくり。ブレッドボードにArduinoやみちびき対応のGPS、SDカードモジュールなどを取り付け、電源オンですぐロギングが開始されるプログラムを書き込んだロガーを作成していきます。はんだ付けが初めての方もいましたが、みなさん無事動作するロガーが完成。

その後は、昼食をとりながら実際にモエレ沼公園の地図とにらめっこをして描く模様を用紙にかいてもらいます。

描き終わったら、スノーシューをはいていざ出発。大体1時間前後の工程で、モエレ沼公園に地上絵を描いていきます。

我々ディレクター、スタッフも一緒に同行したりしていますが、スノーシューの数が足りないメンバーは冬靴で頑張ってついていきます。

 


スノーシューを使わない場合

が、雪が深すぎて50mくらい進むのでも一苦労、普段の運動不足がたたり、太ももに疲れが蓄積されていきます。


スノーシューの場合

明らかに雪に残る足跡が違いますね。

無事みなさん歩き終わり、結果を確認していきます。

参加者のみなさんには、雪原の上だと雪がないモエレ沼とまた違って目印になるものが雪で隠れてたりなかなか難度が高いことを感じていただけたかと思います。

実際に、作成したロガーでうまく記録できた方や、振動や雪原で転ぶなどで途中までの軌跡が残ってしまっているなど、我々も成層圏気球のspace-moereプロジェクトで試行錯誤してデータを取得することをちょっとでも体験していただけたかと思います。

電子工作体験と、そして屋外活動、体も頭もフルに使った1日、参加者のみなさまお疲れさまでした!

 

少しだけ技術的な話について…

今回、ワークショップで利用したGPSの部品(GPSモジュールなんて言ってたりします)などは、札幌市内ですと梅沢無線さん(狸小路八丁目)で購入することができます。部品の中にはないものもありますのでそういった場合は、電子工作する人はほぼ誰もが知っている「秋月電子」というオンラインショップでも購入することができます。

GPSはいろいろな種類がありますが、space-moereプロジェクトでは、高高度の高さ(上空35kmなど)でも高さを取得できるものを採用していたりします。部品を購入する際に、その部品のデータシート、技術資料などを読み解き、目的に応じた位置情報の精度が取得できるかなどを確認して購入したりしています。

モエレの雪上絵 GPSロガー最終版

1月9日(明後日!)はモエレの雪上絵のワークショップなので、やり残していたコードの追加をしていきます。
SDカードに保存される GPS.LOG というcsvファイルですが、起動するたびに後ろにデータが書き足されていく状態のままになっています。
これだと、使い始める前にカードを初期化しなければならず面倒なので、今回は、起動するたびに新たなファイル名でログを残していく仕様にしたいと思います。

偉そうに書いていますが、実はArduinoはあまり馴染みがないのでちょろっとググったところ、
SD.exists( String ) というのが存在するので、一番安直な方法で書いてみました。
存在しない新しいファイル名を取得する関数。

String getNewFileName(){
  
  String s;
  int fileNum = 0;

  while(1){
    s = "GPS_";
    if (fileNum < 10) {
      s += "00";
    } else if(fileNum < 100) {
      s += "0";
    }
    
    s += fileNum;
    s += ".log";
    
    if(!SD.exists(s)){
      break;
    }
    
    fileNum++;
  }

  return s;
}

あとは、起動時、SDカードを初期化した後で呼んでやって変数に代入しておいて、書き込み時に使うだけです。

fileNameToWrite = getNewFileName();

全体はこんな感じ。

#include <TinyGPS++.h>
#include 
#include 

#define SERIAL_BAUD 9600

const int GPS_RX = 8;
const int GPS_TX = 9;
const int LED_PIN = 6;  //for LED

const int CHIP_SELECT = 4;  //for SD

TinyGPSPlus gps;
SoftwareSerial gpsSerial(GPS_RX, GPS_TX);
String fileNameToWrite;

void setup() {

  Serial.begin(SERIAL_BAUD);
  while (!Serial) {} // wait
  Serial.println("serial initialized\n");

  gpsSerial.begin(9600);

  setupSD();
  fileNameToWrite = getNewFileName();
  Serial.println( fileNameToWrite );

  pinMode(LED_PIN, OUTPUT);
  
}

void loop() {

  while (gpsSerial.available() > 0) {
    
    char c = gpsSerial.read();
    //Serial.print(c);
    gps.encode(c);

    if (gps.time.isUpdated()) {

      writeData();

      Serial.print("year : "); Serial.println(gps.date.year());
      Serial.print("mon : "); Serial.println(gps.date.month());
      Serial.print("day : "); Serial.println(gps.date.day());

      Serial.print("hour : "); Serial.println(gps.time.hour());
      Serial.print("min : "); Serial.println(gps.time.minute());
      Serial.print("sec : "); Serial.println(gps.time.second());

      Serial.print("lat : "); Serial.println(gps.location.lat(), 6);
      Serial.print("lng : "); Serial.println(gps.location.lng(), 6);
      Serial.print("alt : "); Serial.println(gps.altitude.meters());

    }
  }
}


String getNewFileName(){
  
  String s;
  int fileNum = 0;

  while(1){
    s = "GPS_";
    if (fileNum < 10) {
      s += "00";
    } else if(fileNum < 100) {
      s += "0";
    }
    
    s += fileNum;
    s += ".log";
    
    if(!SD.exists(s)){
      break;
    }
    
    fileNum++;
  }

  return s;
}


void setupSD() {
  
  Serial.print("Init SD.");
  
  if (!SD.begin(CHIP_SELECT)) {
    Serial.println("Card failed, or not present");
    while (1);
  }
  Serial.println("SD initialized.");
}


void writeData() {

  File dataFile = SD.open(fileNameToWrite, FILE_WRITE);

  if (dataFile) {

    digitalWrite(LED_PIN, HIGH);

    String str;
    str = String(gps.date.year());
    str += "/";
    str += String(gps.date.month());
    str += "/";
    str += String(gps.date.day());
    str += ",";
    str += String(gps.time.hour());
    str += ":";
    str += String(gps.time.minute());
    str += ":";
    str += String(gps.time.second());
    str += ",";
    str += String(gps.location.lat(), 6);
    str += ",";
    str += String(gps.location.lng(), 6);
    str += ",";
    str += String(gps.altitude.meters());

    dataFile.println(str);
    dataFile.flush();
    digitalWrite(LED_PIN, LOW);

  } else {
    Serial.println("error opening log");
    Serial.println(fileNameToWrite);
    
    
    digitalWrite(LED_PIN, LOW);
  }

  dataFile.close();

}

GPS_000.LOG
GPS_001.LOG
GPS_002.LOG

といった感じで起動するたびに新しいファイルが保存されていきます。

Gメールの添付画像をGASでGoogle Drive に保存

福井の堆積場にはハイクカムを設置して撮影を始めた雪堆積場のタイムラプスですが、忘備録的にシステムの紹介。
ハイクカムにはSIMを挿すスロットがあり、Hyke Works 経由でメール添付で最新画像が送られてきます。
今回はgmailのアドレスを新しく取得して、ハイクカム側でそのアドレスを指定しています。
APNの設定や、画質の設定、時間間隔の設定などもあります。今回は5分間隔でgmailのアドレスに送られてくるというわけです。
これをどうにかしてローカルにごっそり保存しておいて展示の時に使いたいというのが今回のお題です。

いくつか方法はありそうですが、今回はサーバで動くGoogle Apps Script(GAS) を使ってみました。
Google Drive上に専用のフォルダを準備して、HykeCam からのメールに添付された画像をそのフォルダに保存。
もちろんGASからではローカルには触れることができないので、
展示するときは、Google Drive のデスクトップアプリで同期してしまおうという作戦です。

*FOLDER_ID はgoogleDrive上のフォルダに振られているランダムな(?)文字列です。アクセスすればURLの下にくっついてます。
*SEARCH_TERM は、検索条件ですが、HykeCamからの未読メッセージということにしました。
*フォルダにファイルを作って、最終的には既読にし、削除するとこまでやっています。(容量を気にして)


const FOLDER_ID = ‘xxxxxxxxxxxxxxxxxxxxxxx’;
const SEARCH_TERM = 'from:(HykeCam) is:unread';

function fetchFile(){
  
  const folder = DriveApp.getFolderById(FOLDER_ID);
  const threads = GmailApp.search(SEARCH_TERM, 0, 10);
  const messages = GmailApp.getMessagesForThreads(threads);

  for(const thread of messages){
    for(const message of thread){
      
      const attachments = message.getAttachments();
      for(const attachment of attachments){
        folder.createFile(attachment);
      }
      
      GmailApp.markMessageRead( message );
      GmailApp.moveMessageToTrash( message );
      
    }   
  }
}

というわけでコードは無事に動いていたら、実行するトリガーを1分間隔に設定して準備完了。
明日は月寒の堆積場にカメラ設置に行ってきます。
それが済めば、あとは雪が降って堆積場が稼働するのを待つだけです!

実験環境を作る#5 – 実験しやすいように整えていく

前回、ある程度厳寒環境の構築ができたので、今回は実験の精度を高めたり実験をスムーズにするために、実験環境を整えていきます。

ドライアイスとエタノールの受け皿は、ホームセンターで買ったアルミ製の受け皿と、ロガーを置くためのバット。

主な金属の中で熱伝導率で見ると

銀>銅>金>アルミニウム>マグネシウム>亜鉛>鉄>スズ>鉛

となっており、受け皿として手に入れれるものでアルミニウムはよさそうです。(銅製があればなおよいですが)

また、実験後に受け皿にたまったエタノールなどを処理する際など扱いやすいようにするために、発泡スチロールの側面に靴棚などで使う棚レールを設置してみました。

小さい改良点ですが、少しずつですがただの発泡スチロールが実験装置らしくなってきました。

 

その作業と並行して、来年2月5日からの展示準備もがしがし進めながら、という状況です。
https://siaflab.jp/wic2021/

実験環境を作る#4 – 日本の最低温度記録を更新

前回の実験の反省を踏まえて、今回は最初からエタノールにドライアイスを浸した状態で、かつその表面積を広く取りできるだけ空気を冷やす方法で取り組んでみます。

エタノールをドライアイスにかけると、もわっと霧がかり、冷気を感じることができます。

準備ができたのであとはひたすら待って計測。

20分くらいたったところで、前回を大きく超える数値に。ドライアイスに浸しているエタノールの温度はマイナス70.8℃に。ここまでくると肌感での想像は難しいですね。

空間内の底につけたプローブの温度も-58.1℃で、キンキンに冷えた空気になっているようです。

今回は2Kgのドライアイスでどれくらい継続して冷やすことができるかということも計測の目的でしたので、最終的な温度推移の結果はこちら。

グラフの青い線が底部の温度になるのですが、大体10時間はマイナス50℃以下を継続して記録できることがわかりました。

 

 

 

堆積場視察@月寒東第2地区

月寒にある堆積場の視察に行ってきました。市街地にある堆積場で、市の予定搬入量は5万立米ですが、民間の搬入もありますので、かなり広い印象です。

雪対策室の方々にご同席いただいて打ち合わせさせていただのち、現場も見せていただきました。関係者のみなさま、丁寧なご対応いただきありがとうございます!

電気もお借りできますし、電柱もあって見晴らしも良く申し分ありません。楽しみです!

 

 

iPad LiDAR 実験 #03

昨日、岩見沢でまとまった雪が降ったと聞き、モエレ沼公園での収録後に、小町谷さんと除雪の跡を探しに行ってきました。道央道で40分ほど走って岩見沢SAに入り、雪の集められていそうな奥へ車を進めて停車。

ドーザーが押し潰した圧雪の上をイイ感じで新雪が覆っています。

残念ながらiPadのLiDARではこのディテールはキャプチャできない…

ちょっと不審ですが、誰がやってもこうなります。iPad Proの性能を引き出すのはあくまでも身体です。

凹凸の激しい部分でも試してみます。

人工物とのコンビネーションに盛り上がる小町谷さん。

このあと岩見沢市内を回りながら、何箇所かで試しました。やはりディティールをきれいに残すことが大きな課題ですが、ディティールがつぶれていても、「あ、これは雪っぽい」というものがあり、その理由がなんなのか、といったことをあれこれと話ながら帰路に就きました。除雪後の雪壁は見れば見るほど、様々な表情があって面白いです。中でも、ミルフィーユ状の圧雪にロータリー車の刃の痕が残るものなどはかなりイイということで意見が一致しています。街中を歩くだけで、これほど自然現象の作る形状に出会えるのは、北国の冬ならではです。

録ったデータについては、整形してみて後日ご報告したいと思います。

実験環境を作る#3 – 日本の最低温度記録を目指してみる

前回で準備が整いましたので、実際に低温環境を作成して温度をはかっていきたいと思います。

https://data-logger.siaflab.jp/2020/12/04/%e5%ae%9f%e9%a8%93%e7%92%b0%e5%a2%83%e3%82%92%e4%bd%9c%e3%82%8b2-%e4%bf%9d%e5%86%b7%e5%ba%ab%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/

https://data-logger.siaflab.jp/2020/12/03/temperature_sensor/

 

今回、低温環境を作るために、ドライアイスを使って保冷庫内の温度を下げていきます。使ったのは1kgのドライアイス2個(大体1個700円程度で購入できました)。

保冷庫の中に、2つ積み、保冷庫内の底と蓋の付近、そして保冷庫の外に温度計のプローブを3つセットして計測開始です。

蓋をしめると一気に温度計の数値が下がっていきます。

 

30分くらいたったところでの温度は、左上T1が-27.6℃=保冷庫内の底、T2が-0.2℃=保冷庫内の蓋側、T3,T4は箱の外となっています。
最初の下がる勢いはなくなったのですが、全体的にゆっくり下がっていくのを計測できます。

ただ、この状態で最終的に1時間近く観測しても、-34℃が限界でした。

2020/12/03,18:45:52,18.0,18.0,18.1,OL - 観測開始時
2020/12/03,19:10:07,-34.2,0.6,17.3,OL - 最低気温

この状態からドライアイスはとけてないのですが徐々に気温が上がってきました。
原因としては、現在のところ推測ですが、ドライアイスが気化した際にでるドライアイスのふわふわ(成分は???)が空気の熱伝導を妨げて、下がる力が弱まった?などが考えられそうです。

ここで、新たに色々調べ、熱を空気に伝える触媒としてエタノールにドライアイスを浸して、実験を継続することにしました。

エタノールにドライアイスを浸した状態で、さらに観測を継続します。

ここから4つ目のプローブをエタノールの温度を観測できるようにした状態にしました。

すると、先ほどよりもぐんぐん温度が下がっていきます。最終的に、この日、エタノール自体は-57.7℃、保冷庫の底の気温は-34.8℃あたりまで観測することができました。

ドライアイスの温度が-80℃近いことを考えると、まだまだ改善の余地はありそうですが、一旦気温は-30℃を超えることはできましたが、日本の史上最低気温は-41℃とのことで、そこまでは到達できませんでした。(北海道旭川で最低気温-41℃が観測史上最も低い最低気温 – wikipedia)

次回の課題としては、この最低気温を超えることが目標になりそうです。

実験環境を作る#2 – 保冷庫を作ってみる

高精度温度計の準備ができたところで、発泡スチロールの箱を低温環境を作るための保冷庫(と仮に呼びます)を準備します。

超低温環境を作るならば、中を覗きたい!というわけで、360度カメラが入るように加工します。結露の問題があるので、慎重にする必要があります。やっていることは見ればわかるので、今回は写真で紹介します。細かい作業は小町谷さんにお願いします!

 

 

ここまで来て、今日は実機が届かないことが判明!

というわけで、カメラを入れるのは次の実験日に持ち越すことに…残念。

 

 

この日、この後の実験の様子は、次回レポートしたいと思います。(↓ユニフォームっぽいですね)

 

 

実験環境を作る#1 – 高精度温度計を使ってみる

このプロジェクトの根幹でもある、「データを取得する」という行為をするにあたり、これまでいろいろな実験の中で、「基準となるデータをどう定義して取得できるようにするか」というのが課題としてあがってきました。

今回、高精度の温度計を使って、これから作成していく自作データロガーデバイスの取得した数値などがきちんと精度が出ているか、どんな特性があるかどうかなどを把握できるようにしたいと思います。

利用するのはTC0304という温度計。4つのプローブ(温度を測る部分)を接続して、4つの温度を同時に測ることができる温度計です。温度計自体はその用途や機能によって求められる精度が違ってくるので、家庭用の室内の温度計のような数百円で測れるものから、産業用や研究用に利用されるような数十万・数百万円以上するようなものまで存在しています。

TC0304

プローブ

PCにつないでリアルタイムロギング

計測グラフ

TC0304に付属するソフトウェアを使って、リアルタイムに温度計の状況を確認することができます(温度計はRS232のステレオピンジャック-PC側はUSBのシリアル通信)。ソフトウェア側ではCSVでのデータ保存ができたりします。

これで、温度の方は記録する環境ができたので、次は計測できる実際の環境を作るフェーズに移行していきます。

GPSログのビジュアライズ#01

作りかけているGPSロガーですが、ちょっと持ち歩いてみた感じ、どうやら動いていそうなので、ログを見てみたいと思います。

保存されている、GPS.LOGを開いて、一行抜き出してみると(詳細は隠しています)、こんな感じ。

2020/12/2,9:44:17,43.xxxxxx,141.xxxxxx,39.60

1行がカンマで区切られたCSVで、

日付 , 時間, 緯度, 経度, 高度

となっています。ひとまず、緯度と経度をプロットしてみたいと思います。python でサクッとできるとスマートなのかなとも思いますが、使い慣れてないのでやめたい。Processing なのか、openFrameworks なのか、実は使い慣れている Objective-C++ とOpenGLでやるのが最終的に速い気がするのですが、環境としてはマイナーなのでやめた方がよいかもしれないですね…

せっかくなので、Python でやってみることにします。

ちょっと調べてみると、csv周りは pandas 、グラフ周りは matplotlib がよさそうなので、これらをpipでインストールしてみました。pipが古いと言われましたが放置して、デスクトップにおいた先ほどの “GPS.LOG” を、”gps.csv”にリネーム。(あとで確認したら、そのままでも読めました…)

とりあえず、Terminal から Python3 を立ち上げて、読み込み&コラムに適当な名前を放り込んでダンプしてみると、

>>> import pandas as pd
>>> import matplotlib.pyplot as plt
>>> df = pd.read_csv('/Users/h/Desktop/gps.csv', names=['date', 'time', 'lat', 'lng', 'alt'])
>>> print(df)
            date      time        lat        lng   alt
0       2000/0/0  23:59:42   0.000000    0.00000   0.0
1       2000/0/0  23:59:43   0.000000    0.00000   0.0
2       2000/0/0  23:59:44   0.000000    0.00000   0.0
3       2000/0/0  23:59:45   0.000000    0.00000   0.0
4       2000/0/0  23:59:46   0.000000    0.00000   0.0
...          ...       ...        ...        ...   ...
19114  2020/12/2   9:44:37  43.xxxxxx  141.xxxxx  40.6
19115  2020/12/2   9:44:37  43.xxxxxx  141.xxxxx  40.6
19116  2020/12/2   9:44:38  43.xxxxxx  141.xxxxx  40.6
19117  2020/12/2   9:44:38  43.xxxxxx  141.xxxxx  40.6
19118  2020/12/2   9:44:39  43.xxxxxx  141.xxxxx  40.7

[19119 rows x 5 columns]

という感じで読み込めました。次は、lat, lng を xy でプロットしたいので、しばし検索したところ、scatter という関数をみつけました。

plt.scatter(df['lng'],df['lat'])

リターン。何も起きず。

plt.show()

リターンすると、ウィンドウが開きました。こんな感じ。

なんとなく緯度経度でプロットされてそうな気配。簡単すぎて拍子抜けしていると、丁寧にUIがついている!ことに気づきました。ルーペを使って拡大すると、

きれいに録れてます。よかった。

コードをまとめると、

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('/Users/h/Desktop/1202_tesetGPS.LOG', names=['date', 'time', 'lat', 'lng', 'alt'])
plt.scatter(df['lng'],df['lat'])
plt.show()

たったこれだけでした。Pythonユーザが多いのも納得できます。

簡単なので、気になっていることを確認してみます。というのも、高度情報の精度がかなり怪しい気がしていて、何かのタイミングで確認しないといけないと思ってたところでした。

単なる折れ線グラフはこれで書けます。

plt.plot(df['alt'])

リターンして、show()すると、

!!!

これは怪しいというか、全然あてにならない?準天頂衛星のみちびき対応のモジュールなのでちょっと期待してたのですが。。。ライブラリのバグ?の可能性は検索する限り報告されてなさそうですし、、、ただ、前半の値が安定している部分以外は、部屋に置いていた時間である可能性もなくはないので、もうちょっと詳細に検証が必要です。今は時間がないのですが、いずれ検証したいと思います。

GPSロガー改良 #02

前回は、GPSからの受信データを簡単に扱うことのできるライブラリ、TinyGPS++を使ってみました。今回はSDカードに書き込む部分を追加する予定でしたが、「TinyGPS++ の、location.isUpdated() がtrueのときに、緯度/経度/高度をSDカードに書き込む、という部分は、それほど難しくなく実装できるうえ、これでは時間の情報が残らないため、GPSのログとしては物足りません。なので、緯度/経度/高度だけでなく、日付や時間を一緒に残すように書き換えてみたいと思います。

Arduino IDEでは、ライブラリの中身をエディタから参照できないので(僕が知る限り)、ひとまずライブラリの中身をの覗いて作戦を立てます。

/Arduino/libraries/TinyGPSPlus/src/TinyGPS++.cppとヘッダ をXcodeで開いてツラツラと眺めてみたところ、時間が更新されたかどうかは、TinyGPSTimeのupdated というフラグを見てやるのがよさそうです。

TinyGPSDateという構造体もあって、日付をまたぐ場合は、こいつのupdatedを見ないといけないかな?とも思いましたが、それって基本的に時間も更新されてるはずなので、TinyGPSTime だけ見ればよいのかなと思います。ただ、日付が入っているGPSのセンテンスと、時間が入っているGPSのセンテンスが違ったような気がするので、必ずしも日付と時間が同じタイミングで更新されるかどうかはちょっと怪しいですね。深掘りした方がよいのでしょうが、とりあえず今の段階では、TinyGPS++の時間が更新されたタイミングで、日付、時刻、位置情報を書き込むことにします。なので、受信状態がよければ、基本的に1秒間隔のデータが出来上がるはずです。

ちょっと整えてみたものがこちら。(改行が多いとよく言われますが、僕としてはこれが読みやすいと思っています)

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SD.h>

#define SERIAL_BAUD 9600

const int GPS_RX = 8;
const int GPS_TX = 9;

const int CHIP_SELECT = 4;  //for SD

TinyGPSPlus gps;
SoftwareSerial gpsSerial(GPS_RX, GPS_TX);


void setup() {

  Serial.begin(SERIAL_BAUD);
  while (!Serial) {} // wait
  Serial.println("serial initialized\n");

  gpsSerial.begin(9600);

  setupSD();
}

void loop() {

  while (gpsSerial.available() > 0) {
    
    char c = gpsSerial.read();
    //Serial.print(c);
    gps.encode(c);

    if (gps.time.isUpdated()) {

      writeData();

      Serial.print("year : "); Serial.println(gps.date.year());
      Serial.print("mon : "); Serial.println(gps.date.month());
      Serial.print("day : "); Serial.println(gps.date.day());

      Serial.print("hour : "); Serial.println(gps.time.hour());
      Serial.print("min : "); Serial.println(gps.time.minute());
      Serial.print("sec : "); Serial.println(gps.time.second());

      Serial.print("lat : "); Serial.println(gps.location.lat(), 6);
      Serial.print("lng : "); Serial.println(gps.location.lng(), 6);
      Serial.print("alt : "); Serial.println(gps.altitude.meters());

    }
  }
}


void setupSD() {
  
  Serial.print("Init SD.");
  
  if (!SD.begin(CHIP_SELECT)) {
    Serial.println("Card failed, or not present");
    while (1);
  }
  Serial.println("SD initialized.");
}


void writeData() {

  File dataFile = SD.open("gps.log", FILE_WRITE);

  if (dataFile) {

    String str;
    str = String(gps.date.year());
    str += "/";
    str += String(gps.date.month());
    str += "/";
    str += String(gps.date.day());
    str += ",";
    str += String(gps.time.hour());
    str += ":";
    str += String(gps.time.minute());
    str += ":";
    str += String(gps.time.second());
    str += ",";
    str += String(gps.location.lat(), 6);
    str += ",";
    str += String(gps.location.lng(), 6);
    str += ",";
    str += String(gps.altitude.meters());

    dataFile.println(str);
    dataFile.flush();

  } else {
    Serial.println("error opening gps.log");
  }

  dataFile.close();

}

しばらく走らせてみて、出来上がったファイルはこんな感じです。

住所がばれるのでモザイク入ってます

同じ時刻に2回保存されているのは、時間を更新するセンテンスが2回くるからですかね。。。最後に書き込んだ時刻を見て、重複する場合は書き込まない、とした方がきれいかもですね。

途中で信号が切れた場合どうなるのか、など、ちょっと挙動がわからない部分があるので検証が必要です。5日にSIAFラボのメンバーでちょっと長い距離を歩くので、それまでに動作確認したいと思います。

GPSロガー改良 #01

大雪山に持っていったGPSロガーで録ったデータですが、データの欠損がそこそこありました。受信状態は悪くなかったはずなので、何か他に原因があるのではないかと考えています。GPSモジュールからの信号はシリアルで受け取りますが、いつ何バイト送られてくるかが決まっているわけではないので、SDカードに書き込むタイミングとの問題があるかな?と想像しています。

よく使われているTinyGPS++というライブラリがありますが、容量がそこそこ大きいので、のちのち、あれこれセンサーを載せたいと考えていたため、前回はライブラリは使わず、自分でパースしていました。きちんと動いていましたが、処理が最適とは思えないので、今回は、ひとまずライブラリを使って実装してみたいと思います。

前回持っていったロガーはこんな感じです。冷凍庫の実験で-35℃まで下げた結果、動作がおかしくなりましたが、常温で放置した結果、今のところ動いているようです。(このあたり、きちんと検証していくためにも、まずきちんとモニタリングできる低温環境を作らなければなりません…)

デバッグ用にLEDがついてます。

ひとまず、ライブラリを使って受信するところまでのコード。

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

#define SERIAL_BAUD 9600

const int GPS_RX = 8;
const int GPS_TX = 9;


TinyGPSPlus gps;
SoftwareSerial gpsSerial(GPS_RX, GPS_TX);


void setup() {

  Serial.begin(SERIAL_BAUD);
  while (!Serial) {} // wait
  Serial.println("serial initialized\n");

  gpsSerial.begin(9600);

}

void loop() {

  while (gpsSerial.available() > 0) {
    char c = gpsSerial.read();
    Serial.print(c);

    gps.encode(c);
    if (gps.location.isUpdated()) {
      Serial.print("lat : "); Serial.println(gps.location.lat(), 6);
      Serial.print("lng : "); Serial.println(gps.location.lng(), 6);
      Serial.print("alt : "); Serial.println(gps.altitude.meters());
    }
  }
}

シリアルモニターに返ってきているのを確認できました。

次回、SDカードに書き込む部分を追加していきますが、ここでタイミングを考えないと前回と同じ結果になる気がします。ひとまず、一定間隔で書き込むのではなく、受信できているときだけ、緯度/経度/高度をSDカードに書き込んでみたいと思います。

 

大雪山VR動画公開

https://youtu.be/AQ7V0IVCxlI

10月26日に大雪山に行ってきました。編集自体はとうの昔に終わっていたのですが、タイミングを計りかねて公開できていませんでした。位置付けとしてはプロジェクトのキックオフです。EDL&RV では、引き続き、ロケ撮影のVR動画をアップしていきたいと思いますので、SIAFラボのYoutubeチャンネルもチェックしていただければと思います。

この日に録ったデータについては、また改めてポストしたいと思います。

福井堆積場視察

昨年もお世話になった福井の雪堆積場に挨拶に伺いました。

改めてご説明いただきましたが、こちらの堆積場は、谷の底から堆積を始めて、最終的には山になるとのことで、インターバル撮影用のカメラの位置と角度の狙いどころがなかなか難しいところです。昨年設置したカメラ(ハイクカム)がまた設置したままになっていたので(!)SIAFラボの石田さんが、取り外しのためイントレに登りました(くれぐれも無理なくお願いしたい…)。カメラの首振りをできる機構を考える必要アリなので、一度回収して、仕込んでから改めて設置に伺うことにしました。

北陽工業さんには、大変なご協力をいただいており、今回も、カメラの位置や撮影方法まで、色々なアイディアをいただきました。

例年、年末に北海道神宮周辺の雪が入るのが最初とのことで、それまでによい画角が見つけて撮影を始められたらと考えています。

管理をしている北陽工業さんの事務所から。五天山が見えます。
札幌中心部と比べると雪が多い…
SIAFラボのロゴ入りヘルメットとかあった方がよいのか。
この谷(?)が雪で埋まります!

 

iPad LiDAR 実験 #02

雪が少し降ったので、iPadのLiDARでもう少しソリッドなモデルを得るべく、手稲山に行ってきました。まだスキー場はオープンしていないものの、傾斜を使ってスキーの練習をしている家族など、思ったより人がいて驚きました。どこへ行っても遊んでいる人がいるのは、北海道ならではかなと思います。

雪自体は、まだ壁と言えるようなものにはなっていないので、地面にできた轍や雪塊をスキャンしてみました。今まで気づきませんでしたが、とにかくLiDARのセンサを対象物に近づけると(10cm前後)、そこそこエッジの効いたというか、機械学習弱めのデータ(?)が得られることがわかりました。ただし、スキャンしている姿がちょっと不審なので、あまり人目につかないようにやっていきたいと思います。

iPadでLiDARを使ったアプリを開発するには、今のところARKit を使うようですが、デプスだけを抜き出してくることは現時点ではできないようです。これについては、またポストしたいと思います。

冷凍庫実験 #01

車載冷凍庫とドライアイスを使った簡単な実験を実施しました。ひとまず、低温試験ができるような環境を自作できるのかを検証することが目的です。

今回準備したのは、-22℃まで冷える車載冷蔵庫と、ドライアイス(2Kg)、アナログの温度計です。

車載冷凍庫は、2時間ほどかけて-20℃を前に下げ止まり。ドライアイス2Kg を入れてから急激に冷えて1時間経たずに-35℃前後まで下がったものの、そこから冷えず。

今回、車載冷凍庫の温度計はエラー表示になってしまったので、信用できる正確な温度計が必要。ちなみに、今回使った温度計はAmazonでとりあえず見つけてきたもの。安いものは低温が測れないものが多いけど、これは -50℃対応とのことだったので買ってみました。(https://www.amazon.co.jp/gp/product/B000FHU9D6)誤差±1℃とのことなので、この実験をするには問題はなさそうですが、グラフを作ったりするならば、やはりデータで残せるもので信頼できるもの(高価でないもの)が望ましいです。

次回は、車載冷凍庫ではなく、発泡スチロールの箱とドライアイスだけを使うことに決定。

少し検索してみると、北海道の観測史上の最低気温は、明治35年(1902年)1月25日、上川測候所(現在の旭川地方気象台)で記録された-41.0度で、これは日本最低気温(富士山頂より低い)のようです。

というわけで、-50℃を目指して、冷凍庫(自作極限環境/自作耐用試験環境)を作っていきたいと思います。

ドライアイスを入れた図。なんとなく入れておいたロガーは最終的に正常に動作していませんでした。
この日の最低温度

iPad LiDAR 実験 #01

車の温度計で-4℃

少し雪が降ったので、iPad Pro のLiDARで雪や氷の形状のスキャンのテストをしてきました。

オープンを控えた札幌国際スキー場の駐車場では、既にドーザーが稼働しており、壁とは言えないまでも、雪が高く積み上げられていました。とはいえ、駐車場に入ることができないので、小樽方向にもう少し進んで、除雪車の転回スペースで実験しました。

スノーバイクをピックアップに載せて遊びにきていたお兄さんの話だと、真冬になるとここからスノーバイクで余市岳の頂上まで行くこともあるとのこと。ホワイトアウトしたら命がけだけどね!とにこやかに話してらっしゃいました。(プロジェクト的には、こういった方々にご協力いただきたい…)

大雪山で、Structure センサを使ったときは、氷は雪はうまくスキャンできませんでしたが、LiDARでは特に問題なくスキャンできました。(ひと安心)

ただ、ディティールがヌルッと平均化される感じがどうにも気持ち悪いので、なんとかしたいところです。

ぬるい。