Hatena::ブログ(Diary)

滴了庵日録 このページをアンテナに追加 RSSフィード

2016/04/08(Fri)

歩くミニ四駆をWebからコントロール

Webブラウザからインターネット経由で歩くミニ四駆をコントロールできるようにしてみました。

Web系・クラウド系はまったくの未経験なので、お手軽に使えるともっぱらの噂のMilkcocoaを使うことにしました。GPduinoにはBLEしか通信機能がないので、Android端末を介してネットワークに接続しています。

D


先日の大阪版IoT縛りの勉強会!IoTLT大阪 Vol.2で発表してきました。


送信側 (Webブラウザアプリ/JavaScript)

HTMLUIを記述し、milkcocoa.js と アプリのスクリプト(ここではcontroller.js)を読み込みます。

<script src='https://cdn.mlkcca.com/v2.0.0/milkcocoa.js'></script>
<script src="controller.js"></script>

スクリプトはいたって簡単です。

  1. MilkCocoaのオブジェクトを生成する
  2. データストアのオブジェクトを生成する
  3. ボタンが押されたらデータをsendする

これだけです。

window.onload = function(){
  var buttonUp    = document.getElementById('up');
  (中略)
  var milkcocoa = new MilkCocoa("アプリのID.mlkcca.com");
  var ds = milkcocoa.dataStore('gpduino');
  (中略)
  buttonUp.onclick = function() {
    (中略)
    ds.send({direction: 'up'});
    (後略)

つまらないものですが、ソースを置いておきます。使うときはアプリのIDを書き換えてください。

ソース


受信側 (Androidアプリ/Java)

KonashiのSDKを使う都合上、WebアプリではなくJavaのネイティブアプリで実装しました。

JavaでMilkcocoaにアクセスするためにMilkcocoa SDK for Androidを利用します。こちらからダウンロードします。


GitHubにもあがっていますが、2016年4月日現在、メンテが滞っており最新版ではないようです。こちらを使うとsendのイベントリスナーでヌルポインタ例外が発生します。かならず、上記のページからダウンロードしてください。


とりあえず、使うクラスは4つだけ。

import com.mlkcca.client.DataElement;
import com.mlkcca.client.DataStore;
import com.mlkcca.client.MilkCocoa;
import com.mlkcca.client.DataStoreEventListener;

public class MilkKoshianUI extends ActionBarActivity implements View.OnClickListener, DataStoreEventListener {
  private MilkCocoa m_milkcocoa;
  private DataStore m_dataStore;

はじめに以下の処理をします。

  1. MilkCocoaのオブジェクトを生成する
  2. データストアのオブジェクトを生成する
  3. イベントリスナーを登録する
  4. sendを監視する
  (中略)
  public void onCreate(Bundle savedInstanceState) {
       (中略)
    m_milkcocoa = new MilkCocoa("アプリのID.mlkcca.com");
    m_dataStore = m_milkcocoa.dataStore("gpduino");
    m_dataStore.addDataStoreEventListener(this);
    m_dataStore.on("send");
  }

そして、sendがあったらデータを取り出します。あとはBLEでミニ四駆に送信するだけです。

  public void onSended(DataElement dataElement) {
        
    String direction =
      dataElement.getValue("direction");
    (後略)
  }

こちらもソースを置いておきます。使うときはアプリのIDを書き換えてください。

ソース

2016/03/24(Thu)

NT京都2016

NT京都2016に出展しました

2016年3月20日に京都西院の春日幼稚園・春日神社境内で開催されたNT京都2016に出展してきました。

奈良キカイケンのブース

われわれ奈良キカイケンは、スマホでコントロールできるロボットのおもちゃやミニ四駆ラジコンを展示しました。スマホラジコンの制御ボードGPduinoの頒布もしました。おかげさまで、GPduinoは完売いたしました。ご来場いただいた皆様、ありがとうございました。


ミニ四駆ラジコンシリーズ・歩くミニ四駆・倒立振子、およびGPduinoの頒布


多脚せ○とくん と 奈良みやげのビニール鹿

ミニ四駆やロボット

Dm9Recordsさんの倒立振子ミニ四駆。電装系以外はすべてミニ四駆の部品らしい。あの高速なギアで倒立振り子!(クリックで動画が見れます)


古家さんの四輪オムニホイールロボット。デフギアを応用して3個のモーターで(x,y,θ)方向を駆動。


ユウタさんのプロペラ駆動ミニ四駆・ソーラーミニ四駆・蒸気タービンミニ四駆。あと、写真撮りそこねたけど、蒸気機関ミニ四駆も!


kuwaさんの走るはちゅね缶と、クランケさん(だったかな?)のテクテク歩くはちゅね缶。かわいい。


S-Thurkさんの変形ロボット


MintiaPさんの各種ホモォ

その他のジャンル

プラモデルを1/1で作る会さんの1/1ヴィーゼル。神社の境内に戦車! ガルパン的な空間がすごくいい。


おおかみさんのエレキバイオリン。僕もたまには音モノもやってみたいな…


はんだるさんの巨大電子部品。こういうネタ性もいいよね…


造形バカさんの電動インラインスケート。人が乗れるのも作りたいなぁ…


ユウタさんのステンレス工作。ひさしぶりにこういう造形系もやりたいなぁ…

今後の課題

  • GPduinoのiOS対応 (NT金沢を目標に)
  • GPduinoのWindows10対応 → shagaくん
  • GPduino/Zero (Arduino M0ベース)の開発
  • Arduino Pro Miniベースの現行GPduinoは小型化?
  • マニ四駆 (ほんとに作るのか?)
  • そろそろミニ四駆の次のネタを!

2016/03/14(Mon)

Androidアプリ開発メモ

プロジェクトの作成

  • Blank Activity アクションバーにメニューが付いてる。古臭い。
  • Empty Activity 空っぽのアクティビティ。こっちを使う。

ボタン

  • Activity を implements OnClickListener にする
  • onCreate()で、Button button1 = (Button)findViewById(R.id.button1); の要領でレイアウトからボタンを取得
  • onCreate()で、button1.setOnClickListener(this); の要領でイベントリスナー登録
  • onClick(View v)を@Overrideで定義。
  • if(v.getId() == R.id.button1){}の要領で処理を記述。

公開されているライブラリの使用

${module}/build.gradleにリポジトリを指定する記述を追記する。

dependencies {
    compile 'com.uxxu.konashi:konashi-android-sdk:1.1.0'
}

Bluetoothの許可

AndroidManifest.xmlを開いたら、以下の二つのパーミッションを追加します。

main.xml

<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>

ネットワークの許可

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

数値 ⇔ 文字列

数値 ⇒ 文字列

String s = String.valueOf(i);

文字列 ⇒ 数値

int i = Integer.parseInt(s);

プロジェクトのコピー

既存のプロジェクトをベースに別プロジェクトを作る方法。(これでいい?)

  • プロジェクトのフォルダを丸ごとコピーして名前を変更
  • Android Studioで、他のプロジェクトを閉じて、Import Projectでコピーしたプロジェクトをインポート
  • app>java>の パッケージ名を Refactor>Renameで変更
  • Javaのソースコードの、パッケージ名やクラス名などを適宜、 Refactor>Renameで変更
  • app>manifests>AndroidManifest.xml の package="パッケージ名"を変更
  • Gradle Script>build.gradle(Module:app) の applicationId "パッケージ名" を変更

2016/02/27(Sat)

Google PlayへのAndroidアプリのリリース

手順メモ。

事前準備

Google Play Developer への登録する。25ドルかかる。

apkパッケージ作成

  • Android Studio のメニューから [ビルド] > [Generate Signed APK...]
  • モジュールを選択する。
  • Key Storeファイル(*.jks)を指定する。初回は[Create new...]で作成する。
    • パスワード、氏名、部署名、組織名、都市名、都道府県名などを適当に入力する。
    • Aliasは、電子署名の名称。べつになんでもいい。
    • Validityは、有効年数。25以上が推奨。
    • Country Codeは、国別コード。日本は、jp または 81。
  • apkパッケージの保存先を指定する。
  • [Build Type:]は、[release]を選択する。
  • [fishish]でapkパッケージが生成される。


ちなみに、もう使うことは無かろうけど、eclipseの場合は、[File] > [Export] > [Export Android Application] から。

アプリ情報の登録

apkパッケージのアップロード

  • [APK] > [製品版] からapkパッケージをアップロードする。

レーティングの設定

  • [コンテンツのレーティング]を開く。
  • メールアドレスを入力する。
  • アプリのカテゴリを選択する。
  • アンケートに回答する。
  • [アプリのレーティングを算定] > [アプリにレーティングを適用]

価格と販売/配布地域を設定

  • [価格と販売/配布地域]を開く。
  • [有料]か[無料]かを設定する。[有料]なら価格を設定する。
  • [配布する地域]は[すべての国を選択]とする。
  • 同意事項をチェックする。

そして、公開

  • 以上すべての準備が整うと、[公開の準備完了] と表示される。
  • ここから[このアプリを公開する]を選択する。
  • 数時間でストアに公開される。

参考URL

2016/02/23(Tue)

CLIラッパの作り方

ネイティブコードのHogeCクラスを含むライブラリHogeC.libを、C#で利用するためのCLIラッパライブラリHogeSharp.dllの作り方をメモします。

プロジェクトの作成

[ファイル]>[新しいプロジェクト]>[テンプレート]>[Visual C++]>[CLR]>[クラスライブラリ]で新規プロジェクトを作成します。ここでは HogeSharp という名前にします。

プロジェクトの設定

  • ネイティブライブラリのヘッダ HogeC.h を任意のフォルダに置きます。ここではソースフォルダの下のIncフォルダとします。
  • ネイティブライブラリ HogeC.lib を任意のフォルダに置きます。ここではソースフォルダの下のLibフォルダとします。
  • [プロジェクト]>[プロパティ]>[構成プロパティ]>[VC++ディレクトリ]>[インクルードディレクトリ]に、Incを追加します。(;で区切ります)
  • [プロジェクト]>[プロパティ]>[構成プロパティ]>[VC++ディレクトリ]>[ライブラリディレクトリ]に、Libを追加します。(;で区切ります)
  • [プロジェクト]>[プロパティ]>[構成プロパティ]>[リンカ]>[入力]>[追加の依存ファイル]に、HogeC.libを追加します。(;で区切ります)
  • その他、HogeC.libがさらに別のライブラリに依存している場合、それらも追加します。(たとえば、WinSock APIを使用していて ws2_32.libに依存しているなど)

ソースファイル一覧

resource.h

特に修正不要。

AssemblyInfo.cpp

名称、著作権表示、バージョン情報などの属性を適当に記入するだけです。

Stdafx.h, Stdafx.cpp

使用するインクルードファイルやライブラリをStdafx.hに列挙します。(べつに書かなくても良い?)

#include "HogeC.h"
#pragma comment(lib,"HogeC.lib")

Stdafx.cppはただのダミーなので修正不要です。

HogeSharp.h, HogeSharp.cpp

おもにコードを書くべきはここです。

コードの記述

ラッパクラスの宣言

HogeSharp.h に Class1 というクラスが勝手に作られるので、これを Hoge に改名します。このクラスが、public ref classであることに注意してください。C#から使用するクラスは、public ref classでないといけません。ちなみにC#で構造体として使うのであれば、pubilc value classとします。また、クラスHogeは、名前空間HogeSharpに属します。

Hogeクラスには、publicなメンバとしてコンストラクタ、デストラクタ、ファイナライザ、および必要なメソッドを宣言します。ファイナライザというのはCLI特有のものです。C#のデストラクタ~Hoge()に対応するのが、CLIではファイナライザ!Hoge()であり、CLIのデストラクタ~Hoge()は、C#のHoge.Dispose()に対応します。

  • C#のDispose → CLIのデストラクタ
  • C#のデストラクタ → CLIのファイナライザ

また、privateなメンバとして、ネイティブクラスHogeCへのポインタを宣言します。C#から呼び出すラッパクラスは、ネイティブクラス(アンマネージドクラス)の実体をメンバに持てないことに注意してください。

    // CLIのラッパクラス
    public ref class Hoge
    {
    public:
        Hoge();    // コンストラクタ
        ~Hoge();   // デストラクタ
        !Hoge();   // ファイナライザ
        // その他、必要なメソッド
        int Piyo();
        void Huga(int Foo);
    private:
        HobeC* hogeC; // ネイティブクラスへのポインタ
    };
ラッパクラスの実装

HogeクラスをHogeSharp.cppに実装します。

  • コンストラクタでHobeCオブジェクトをnewします。
  • ファイナライザでHobeCオブジェクトをdeleteします。
  • デストラクタではファイナライザを呼ぶことにしておきます。

※ デストラクタではマネージドリソースを開放してからファイナライザを呼び出し、ファイナライザでアンマネージドリソースを解放するべきだそうです。

  • 各メソッドは、ネイディブクラスの対応するメソッドを呼び出します。
using namespace HogeSharp;

// コンストラクタ
Hoge::Hoge() {
    hogeC = new HogeC(); // ネイティブオブジェクト生成
}

// デストラクタ
Hoge::~Hoge() {
    this->!Hoge(); // ファイナライザを呼ぶ
}

// ファイナライザ
Hoge::!Hoge() {
    delete hogeC; // ネイティブオブジェクト解放
}
// ラッパ
int Hoge::Piyo()
{
    return hogeC->Piyo();
}
void Hoge::Huga(int Foo)
{
    hogeC->Huga(Foo);
}
.NETライブラリの使用

ウィザードが吐くコードの中に、すでに using namespace System; があるので、System名前空間のクラスは利用できます。

using namespace System;

String^ hoge;

それ以外の名前空間のクラス、例えばSystem.Drawing.Bitmapを使用したい場合は、下記のように書きます。

#using <system.drawing.dll>
using namespace System::Drawing;

Bitmap^ piyo;
型と参照

ハンドル

C#の参照型に相当する型の変数宣言には、^ をつけます。これをハンドルと呼びます。

Bitmap^ piyo;

この場合のオブジェクト生成(C#でのnewに相当)は、newではなくgcnewを用います。

String^ foo = gcnew String("FOO");


追跡参照

C#のrefに相当する引数宣言には、% をつけます。これを追跡参照とよびます。

// C# からは hoge.piyo(ref foo);のように呼ぶ
void Hoge::piyo(int% foo)

また、C#のoutに相当する引数宣言は、下記のようにします。

// C# からは hoge.piyo(out foo);のように呼ぶ
void Hoge::piyo([Runtime::InteropServices::Out]int% foo) 
文字列の変換

C#のSystem.Stringと、C++のstd::string、Cのchar*の変換は下記のようにします。

#include <msclr/marshal_cppstd.h>
using namespace msclr::interop;

// C#のString => C++のstring, Cのchar*
System::String^ s_cs = L"文字列";
std::string s_cpp = marshal_as<std::string>(s_cs);
const char* s_c = s_cpp.c_str();

// C++のstring => C#のString
std::string s_cpp = "文字列";
System::String^ s_cs = marshal_as<System::String^>(s_cpp);

// Cのchar* => C#のString
const char* s_c = "文字列";
System::String^ s_cs = marshal_as<System::String^>(s_c);

ビルド

ビルドするとHogeSharp.dllができます。

C#アプリでの使用

  • ソースのフォルダにHogeSharp.dllを追加します。
  • [プロジェクト] > [参照の追加] > [参照] で上記DLLを追加します。
  • using HogeSharp; とすれば、クラスHogeが使えます。