脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

HTC Viveでテレポート機能を実装する方法

HTC Viveでコントローラーを利用したテレポートの方法です
こんなのです
f:id:portaltan:20180115183249p:plain

ライブラリとしてgithubで公開されている以下のライブラリを利用させていただきます
github.com

環境

HTC ViveをUnityで開発するにはSteamVR PluginというPluginを利用することになりますが、Unity5.x系とは相性が悪くコントローラーが表示されなかったり一部機能がうまく動かなかったりするので、そういう場合は素直にUnity2017を利用するとすんなり動くことが多いです
(この記事はところどころ5.6.3で書いていますが)
https://www.assetstore.unity3d.com/jp/#!/content/32647

ライブラリimport

import Vive-Teleporter library

テレポート用のライブラリをimportします
githubからそのままダウンロードしてUnityにimportします
https://github.com/Flafla2/Vive-Teleporter

importすると設定を最適なものにするかどうか聞かれるダイアログが表示されるので、問題なければAcceptを選択します
f:id:portaltan:20180115175129p:plain

今回は上記のライブラリにSteamVR Pluginも入っているため、追加でSteamVR Pluginをimportする必要はありません

テレポート機能の作成

地面の作成

まずは移動するための地面を作ります
Groundという名前でCubeを作成し、地面っぽく引き伸ばします

  • position: 0, -0.5, 0
  • Scale: 10, 1, 10
  • (Staticにチェック)
  • (LightProbeをOff)
  • (Lightmap Staticにチェック)

f:id:portaltan:20180115175344p:plain

Windows > Navigationを選び、Groundを選択します

  • Objectタブ
    • Navigate Staticにチェックをチェック
    • Generate OffMeshLinksのチェックを外す
  • bakeタブ
    • bakeをクリックして実行

bakeがうまくいくと以下のようにcubeの上面に水色のエリアが表示されます
f:id:portaltan:20180115175932p:plain

NavMeshの作成

NavMesh prefabをヒエラルキーD&Dします
InspectorのVive Nav Mesh(Script)の項目でUpdate Navmesh Dataをクリックして実行します
そうすると以下のようなマス目と移動の境界線にエフェクトが表示されます
f:id:portaltan:20180115181947p:plain

Pointerの作成

pointer prefabをヒエラルキーD&Dします

  • NavMeshに上記で作成したNavmeshをアタッチ
Cameraの設定

まずは不要なMain Cameraを削除して、Camera Rig prefabをヒエラルキーD&Dします
f:id:portaltan:20180115182310p:plain
次にInspectorから各項目を設定していきます
Camera Rig本体

  • Steam VR_Play Area(script)を削除
  • (Mesh Filter)を削除
  • Mesh Rendererを削除

Camera(eye)

  • Vive Teleporterスクリプトをadd component
    • (Border ReferererとTeleport Viveの項目が追加されます)
  • Teleport Vive
    • pointerに上記で作ったpointerをアタッチ
    • Origin TransformにCameraRig自体をアタッチ
    • Head TransformにCamera(head)自体をアタッチ
    • Navmesh Animatorに上記で作ったNavMeshをアタッチ
    • Fade Materialはライブラリに入っているFadeBlackを選択
    • Controllersのsizeを2に変更
      • Element0にController(left)をアタッチ
      • Element1にController(right)をアタッチ
  • Border renderer
    • Border MaterialでRoom Area Borderを選択

f:id:portaltan:20180115183027p:plain

以上で設定は完了です

確認

デバッグを起動すると以下のようにタッチパッド長押しでテレポートできるようになります
f:id:portaltan:20180115183249p:plain

おまけ

侵入禁止エリアの設定

Cube等のcolliderの設定されている障害物を作成し、Groundに接地させる(めりこませてもよい)
f:id:portaltan:20180115183920p:plain
Inspectorタブでstaticにし、Navigationタブでbakeします
すると以下のようにCubeのまわりだけの水色のスペースが除外されます
f:id:portaltan:20180115184104p:plain
次に忘れずにNavmeshからUpdate Navmesh Dataをクリックします
f:id:portaltan:20180115184221p:plain

この状態でデモを実行するとCubeのまわりだけテレポートできないようになります
f:id:portaltan:20180115184359p:plain

arduinoを最小構成で自作する(atmega328/8MHz/3.3V/内部クロック)

arduinoはいまや様々な種類が出ていて、かつ安価に購入できるので、IoTなどの分野でも幅広く利用されています
しかしarduinoを利用したシステムなどを量産する際に、更に小型化・省コストを狙う際にはarduinoのチップ(atmega328)を利用してarduino自体を自分の必要な構成で自作することが可能です

今回は以下の最小構成で自作します

  • 8MHz(既製品は16MHz)
  • 3.3V駆動(既製品は入力電圧:7V-12V, 駆動電圧:5V)
  • atmega328(既製品についているマイコンチップ)
  • 内部クロックを利用(既製品は外部クリスタルを利用)

必要なもの

  • atmega328
  • Arduino Uno(初期設定/FW書き込み用)
  • ジャンパーケーブル(初期設定/FW書き込み用)
  • ブレッドボード(初期設定/FW書き込み/確認用)
  • LED(確認用)

手順

1. ライブラリやIDEのダウンロード

以下のリンクのMinimal Circuitの項目にあるBreadboard-1-x-x.zipをダウンロードして解凍し、arduinoのhardwareフォルダに配置します
Arduino - ArduinoToBreadboard

  • 私の環境では”C:\Program Files (x86)\Arduino\hardware”にありました
  • ダウンロードするライブラリのversionですが、自分が使っているArduino IDEに対応したものをダウンロードします
    • 私は1.7.11を利用していますが、1.7用がなかったのでBreadboard-1-6-x.zipを使って問題なく動作しました
2. arduino ISPの書き込み

Arduino UNOへISPスケッチを書き込みます
サンプルにデフォルトで入っているので、Open > ArduinoISPを選択してそのままUploadします
f:id:portaltan:20180104125541p:plain

3. arduinoとatmega328の接続

以下の画像の通りarduinoとatmegaを接続します
f:id:portaltan:20180104125614p:plain

4. ブートローダー書き込み

atmegaを利用する際に、何も書き込まれていない素のままのTipを購入した際は一番最初にbootloaderを書き込まなければいけません
書き込み済みのものを購入した場合はスキップしてOKですが、16MHz用のブートローダーが書き込まれている場合は上書きしなければならず、その場合には外部発振子(水晶やセラロック)が必要になります。今回は割愛します

手順1でライブラリをarduinoのhardwareフォルダに配置している場合、boardの項目にAtmega328という項目が追加されているのでそれを選択します
f:id:portaltan:20180104130058p:plain

次にTools > Programmerの項目からArduino as ISPを選択します
(AVR ISPでもArduino ISPでもなくArduino as ISPです)

そうしたらTools > Burn Bootloaderを選択すればブートローダーの書き込みが行われます

5. スケッチ書き込み

ブートローダーは一度書き込めばよいので、不要なケーブルを抜き以下のようにスケッチ書き込み用の構成にします
f:id:portaltan:20180104130451p:plain
この際にArduino UnoについているAtmegaを外さないといけないのですが、これがとても固くて全作業の中で一番大変でした

あとはarduinoから通常のように書き込みをすればブレッドボード上のatmega328へ書き込まれます
試しにblinkを書き込んで動作確認をしてみました
f:id:portaltan:20180104131538j:plain

6. arduinoを外して確認

最後にスケッチ書き込み用のarduinoを外してちゃんと動作するか確認します
外部電源として3.3Vを供給しています
f:id:portaltan:20180104132535j:plain

外部発振子を利用する場合

  • BoardでArduino Pro or Pro Miniを選択
  • ProcessorでAtmeta328(3.3V, 8MHz)を選択
  • 1番ピン10kΩでプルアップ

f:id:portaltan:20180117160831p:plainf:id:portaltan:20180117160836p:plain

Raspberry PiとArduinoをGPIOでシリアル接続する場合は電圧に注意(3.3V/5V)

Raspberry PiArduinoをシリアル接続する際は単純につなぐとそれぞれ電圧が違うので壊れてしまう可能性がある(主にラズパイの方が)

入出力電圧

Raspberry PI

  • 入力電圧
    • 0~0.8V : LOW(OFF)として判断
    • 0.8~1.3V : 不定(不安定でどっちになるかわからない)
    • 1.3~3.3V: HIGH(ON)として判断
  • 出力電圧
    • ON : 3.3V出力
    • Off : GND(出力)

Arduino

  • 入力電圧
    • 0~2.5V : LOW(OFF)として判断
    • 2.5~5.0V: HIGH(ON)として判断
  • 出力電圧
    • ON : 5.0V出力
    • Off : 0V

接続時の問題

RaspberryPi(TX) => Arduino(RX)
ラズベリーパイの出力電圧は3.3Vですが、Arduinoは入力電圧として2.5~5.0Vに対応しているのでそのまま送ってしまって問題ありません

Arduino(TX) => RaspberryPi(RX)
問題なのはこちらです
ラズベリーパイの入力電圧は上記の通り0V~3.3Vですが、arduinoの出力電圧は5Vでこの範囲を超えてしまっています
このまま何もせず接続すると過電圧で最悪ラズパイが壊れてしまいます

解決方法

電圧を下げる

具体的に電圧を下げる方法はいくつもありますが、抵抗分割するのがブレッドボード上などでは一番てっとり早いです
f:id:portaltan:20171226134538p:plainf:id:portaltan:20171226134752p:plain
分圧回路 - Wikipedia

Windows Subsystem for Linux(Bash on Windows)をインストールしてみた(英語OS)

2016年に発表されて2017年に正式リリースされ、最近Windows 10 Fall Creators Updateによって簡単にインストールができるようになったWindows Subsystem for Linuxをインストールしてみた
ちなみに正式名称として「Windows Subsystem for Linux」になったらしく、発表当時のBash on Windowsという名前は非推奨になった

Windows Subsystem for Linuxのインストール

Windows Setting画面を開いて
f:id:portaltan:20171221172110p:plain

Appsを選択して
f:id:portaltan:20171221172221p:plain

Programs and Featuresを選択して
f:id:portaltan:20171221172305p:plain

Turn Windows features on or offを選択して
f:id:portaltan:20171221172359p:plain

Windows Subsystems for LinuxにチェックをいれてOKを押すとダウンロードがはじまる
f:id:portaltan:20171221172510p:plain

ダウンロードが完了すると再起動の確認ダイアログが出るので再起動すればインストール完了

ubuntuのインストール

次に実際にubuntuをインストールする
Microsoft Storeでubuntuを検索してインストールする
f:id:portaltan:20171221172752p:plain

インストールが完了したら起動をクリック
f:id:portaltan:20171221172831p:plain

起動するとターミナルが開いてubuntuで利用するユーザー名とパスワードの入力が促される

Installing, this may take a few minutes...
Installation successful!
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: ユーザ名入力
Enter new UNIX password: パスワード入力
Retype new UNIX password: パスワード再入力
passwd: password updated successfully
Default UNIX user set to: ***
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

メッセージにも書いてあるがwindows アカウントとは関係ないので一致させる必要はない

以上で設定完了

確認とか

$ cat /etc/issue
  Ubuntu 16.04.3 LTS \n \l

$ cat /etc/lsb-release
  DISTRIB_ID=Ubuntu
  DISTRIB_RELEASE=16.04
  DISTRIB_CODENAME=xenial
  DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS"

$ uname -a
Linux DESKTOP-Q0FRENB 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014 x86_64 x86_64 x86_64 GNU/Linux

$ echo $SHELL
  /bin/bash

$ cat /etc/shells
  # /etc/shells: valid login shells
  /bin/sh
  /bin/dash
  /bin/bash
  /bin/rbash
  /usr/bin/tmux
  /usr/bin/screen

とりあえずライブラリのupdateとかしておくといいと思う

$ sudo apt-get update
[sudo] password for hogehoge:
Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease
Get:2 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]
Get:3 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
Get:4 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages [408 kB]
Get:5 http://archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB]
Get:6 http://archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [7,532 kB]
Get:7 http://security.ubuntu.com/ubuntu xenial-security/main Translation-en [179 kB]
Get:8 http://security.ubuntu.com/ubuntu xenial-security/restricted amd64 Packages [7,472 B]
Get:9 http://security.ubuntu.com/ubuntu xenial-security/restricted Translation-en [2,412 B]
Get:10 http://security.ubuntu.com/ubuntu xenial-security/universe amd64 Packages [190 kB]
Get:11 http://security.ubuntu.com/ubuntu xenial-security/universe Translation-en [99.0 kB]
Get:12 http://security.ubuntu.com/ubuntu xenial-security/multiverse amd64 Packages [3,208 B]
Get:13 http://security.ubuntu.com/ubuntu xenial-security/multiverse Translation-en [1,408 B]
Get:14 http://archive.ubuntu.com/ubuntu xenial/universe Translation-en [4,354 kB]
Get:15 http://archive.ubuntu.com/ubuntu xenial/multiverse amd64 Packages [144 kB]
Get:16 http://archive.ubuntu.com/ubuntu xenial/multiverse Translation-en [106 kB]
Get:17 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [681 kB]
Get:18 http://archive.ubuntu.com/ubuntu xenial-updates/main Translation-en [284 kB]
Get:19 http://archive.ubuntu.com/ubuntu xenial-updates/restricted amd64 Packages [8,072 B]
Get:20 http://archive.ubuntu.com/ubuntu xenial-updates/restricted Translation-en [2,672 B]
Get:21 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [565 kB]
Get:22 http://archive.ubuntu.com/ubuntu xenial-updates/universe Translation-en [229 kB]
Get:23 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse amd64 Packages [16.2 kB]
Get:24 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse Translation-en [8,052 B]
Get:25 http://archive.ubuntu.com/ubuntu xenial-backports/main amd64 Packages [4,860 B]
Get:26 http://archive.ubuntu.com/ubuntu xenial-backports/main Translation-en [3,220 B]
Get:27 http://archive.ubuntu.com/ubuntu xenial-backports/universe amd64 Packages [6,612 B]
Get:28 http://archive.ubuntu.com/ubuntu xenial-backports/universe Translation-en [3,768 B]
Fetched 15.1 MB in 3min 59s (63.3 kB/s)
Reading package lists... Done

Unityで3D空間をコントローラーで移動させて、障害物に衝突したらちゃんと止まるようにする

コントローラーを使ってキャラクターを移動させて、障害物にぶつかったら止まるという基本の動作をUnityで実装する方法

つかったもの

Unity version

  • unity 5.6.4f1

ユニティちゃん

Oculus Utilities

コントローラー

  • みんな大好き箱〇コントローラー(PC用)

f:id:portaltan:20171127153135p:plain

準備

床と障害物となる柱を設置

  • 床は3D object > Terrain
  • 柱は3D object > Cylinder

f:id:portaltan:20171127151048p:plain

その前にユニティちゃんを配置

  • import package > custom packageでダウンロードしてきたユニティちゃんパッケージをimport
  • unitychan prefabsをHierarchyにD&Dして配置、位置調整

f:id:portaltan:20171127151631p:plain

スクリプト(今回はunityWalking.cs)を作成してunitychanにセット

  • create > C# script

f:id:portaltan:20171127152004p:plain

Oculus Utilityのimport

  • import package > custom packageでダウンロードしてきたOculus Utilityパッケージをimport

(コントローラーの十字キーの設定)

portaltan.hatenablog.com

開発

以下のサイト様がとてもわかりやすかったので、上から試していってみた
tama-lab.net

1. transform.position

  • 座標を直接書き換えることで移動する
  • 移動というより瞬間移動的なもの
    • 上記の理由より衝突判定を抜けてしまうことが多い
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class unityWalking : MonoBehaviour {
	public float speed = 3f;

	void Update () {
		if (Input.GetAxis("Vertical") > 0){
			transform.position += transform.forward * speed * Time.deltaTime;
		}
		if (Input.GetAxis("Vertical") < 0){
			transform.position -= transform.forward * speed * Time.deltaTime;
		}
		if (Input.GetAxis("Horizontal") > 0){
			transform.position += transform.right * speed * Time.deltaTime;
		}
		if (Input.GetAxis("Horizontal") < 0){
			transform.position -= transform.right * speed * Time.deltaTime;
		}
	}
}

f:id:portaltan:20171127170805g:plain
これで移動はできるようになったがcylinderを突き抜けていってしまうので衝突判定の設定をする

cylinderにはデフォルトでCapsule colliderがセットされているので、unitychanの方にcolliderとrigitbodyを設定する

  • rigidbody
    • use Gravity:オフ
    • Is Kinematic:オフ
  • capsule collider
    • height: 2
    • Center: 0, 1, 0

これで衝突判定されるようになったが、柱にぶつかった時の挙動がちょっと微妙。
f:id:portaltan:20171219190106g:plain

調べればよい解決法があるのかもしれないがとりあえず次の方法を試してみる

2. RigidBody

Rigidbody.AddForce
  • rigidbody
    • use Gravity:オフ
    • Is Kinematic:オフ
  • capsule collider
    • height: 2
    • Center: 0, 1, 0
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class unityWalking : MonoBehaviour {
	public float speed = 10f;
	public Rigidbody rb;

	void Start(){
		rb = GetComponent<Rigidbody> ();
	}

	void FixedUpdate () {
		float x = Input.GetAxis ("Horizontal") * speed;
		float z = Input.GetAxis ("Vertical") * speed;
		rb.AddForce (x, 0, z);
	}
}

rigidbodyに力を加えて押す感じ?慣性で動き続けてしまうので微妙
f:id:portaltan:20171129095022g:plain

Rigidbody.Velocity
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class unityWalking : MonoBehaviour {
	public float speed = 3f;
	float moveX = 0f;
	float moveZ = 0f;
	Rigidbody rb;

	void Start(){
		rb = GetComponent<Rigidbody> ();
	}

	void Update () {
		moveX = Input.GetAxis ("Horizontal") * speed;
		moveZ = Input.GetAxis ("Vertical") * speed;
		Vector3 direction = new Vector3 (moveX, 0, moveZ);
	}

	void FixedUpdate(){
		rb.velocity = new Vector3 (moveX, 0, moveZ);
	}
}
  • 慣性はなくなった
  • ただ衝突判定時に回転してしまう

f:id:portaltan:20171129095155g:plain

これもちゃんと調べればきちんと動く方法があるかもしれないのだが、とりあえず次を試してみる

3. CharacterController

CharacterController.SimpleMove

結論から言うとこのCharacter Controllerを使うと自分の意図してた動きを実現することができた
このCharacter Controllerとはカプセルcolliderと移動機能をセットにしたものでrigidbodyもセットしても反映されないらしいので、上の方法でセットしていたcolliderとrigidbodyは今回はセットしない
その代わりにCharacter Controllerをセットする

  • Character Controller
    • Center : 0, 1, 0
    • Height : 2
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class unityWalking : MonoBehaviour {
	public float speed = 3f;
	float moveX = 0f;
	float moveZ = 0f;

	CharacterController controller;

	void Start(){
		controller = GetComponent<CharacterController> ();
	}

	void Update () {
		moveX = Input.GetAxis ("Horizontal") * speed;
		moveZ = Input.GetAxis ("Vertical") * speed;
		Vector3 direction = new Vector3 (moveX, 0, moveZ);
		controller.SimpleMove (direction);
	}
}

f:id:portaltan:20171129095252g:plain

Unityでシーン遷移するとライトが暗くなる問題

UnityでSceneManager.LoadScene ("scene名")でシーンを移動すると、移動先のシーンのライトが暗くなる問題が発生した。
問題のシーンを遷移せずに初期画面として実行すると正常にライトが表示されるにも関わらず、他のシーンから移動すると暗くなってしまう。
調べてみると何時の頃からかライト情報の取り扱いが変更になったらしい

解決法

  1. 問題のシーンを開く
  2. Window > Lighting > Settingsでライトの設定を開く
  3. 一番下に表示されるAuto Generateのチェックを外し、その隣のGenerate Lightingをクリックする

f:id:portaltan:20171219164738p:plain

以上でシーン遷移後もライトが暗くなる問題は解決できた

raspberryPi3にinfluxdb v1.3をインストールする

以前ラズベリーパイにv1.2のinfluxdbをインストールしましたが、今回はv1.3です
portaltan.hatenablog.com

Install InfluxDB

# ライブラリ設定
$ curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add -
  OK
$ source /etc/os-release
$ test $VERSION_ID = "7" && echo "deb https://repos.influxdata.com/debian wheezy stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
$ test $VERSION_ID = "8" && echo "deb https://repos.influxdata.com/debian jessie stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
  deb https://repos.influxdata.com/debian jessie stable
$ sudo apt-get update

# インストール
$ sudo apt-get install influxdb
$ sudo service influxdb start

# 確認
$ ps aux | grep influx
  nouziru    8210  0.0  0.2   4276  2012 pts/1    S+   12:59   0:00 grep influx
  influxdb 29797 13.1  4.3 800484 38508 ?        Ssl  11:15  13:40 /usr/bin/influxd -config /etc/influxdb/influxdb.conf

$ ss -lntp | grep 808
  LISTEN     0      128               127.0.0.1:8088                     *:*
  LISTEN     0      128                            :::8086                    :::*

$ influxd config
### 各種項目が表示される

influxコマンド確認

$ influx
Connected to http://localhost:8086 version 1.3.7
InfluxDB shell version: 1.3.7

> show databases
  name: databases
  name
  ----
  _internal

> create database debug

> show databases
  name: databases
  name
  ----
  _internal
  debug

> use debug
  Using database debug

> show measurements

API確認

# pingチェック
$ curl -sl -I  http://localhost:8086/ping
    HTTP/1.1 204 No Content
    Content-Type: application/json
    Request-Id: 0c85b3cf-d3f2-11e7-8003-000000000000
    X-Influxdb-Version: 1.3.7
    Date: Tue, 28 Nov 2017 04:10:20 GMT

# database確認
$  curl http://localhost:8086/query --data-urlencode "q=SHOW DATABASES"
  {"results":[{"statement_id":0,"series":[{"name":"databases","columns":["name"],"values":[["_internal"],["debug"]]}]}]}

# テストデータ投入(measurement: test_measurement / field: record1, 2)
$ curl -i -XPOST "http://localhost:8086/write?db=debug" --data-binary 'test_measurement record1=100'
$ curl -i -XPOST "http://localhost:8086/write?db=debug" --data-binary 'test_measurement record2=200'
$ curl -i -XPOST "http://localhost:8086/write?db=debug" --data-binary 'test_measurement record1=300,record2=400'

# テストデータ確認
$ curl -G 'http://localhost:8086/query?db=debug' --data-urlencode 'q=SELECT * FROM test_measurement'
  {"results":[{"statement_id":0,"series":[{"name":"test_measurement","columns":["time","record1","record2"],"values":[["2017-11-28T04:16:19.266486831Z",100,null],["2017-11-28T04:16:28.640633831Z",null,200],["2017-11-28T04:16:44.255827602Z",300,400]]}]}]}

# テストデータ確認(pretty=trueをつけると改行されて表示される)
$ curl -G 'http://localhost:8086/query?db=debug&pretty=true' --data-urlencode 'q=SELECT * FROM test_measurement'
{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "test_measurement",
                    "columns": [
                        "time",
                        "record1",
                        "record2"
                    ],
                    "values": [
                        [
                            "2017-11-28T04:16:19.266486831Z",
                            100,
                            null
                        ],
                        [
                            "2017-11-28T04:16:28.640633831Z",
                            null,
                            200
                        ],
                        [
                            "2017-11-28T04:16:44.255827602Z",
                            300,
                            400
                        ]
                    ]
                }
            ]
        }
    ]
}

# influxコマンドで確認すると
$ influx
Connected to http://localhost:8086 version 1.3.7
InfluxDB shell version: 1.3.7

> use debug
  Using database debug

> select * from test_measurement
  name: test_measurement
  time                record1 record2
  ----                ------- -------
  1511842579266486831 100
  1511842588640633831         200
  1511842604255827602 300     400