ラベル android の投稿を表示しています。 すべての投稿を表示
ラベル android の投稿を表示しています。 すべての投稿を表示

2012年7月28日土曜日

Androidアプリにコマンドライン(CLI)から署名する

rxconsoleの署名に失敗してしまい、修復不可能にしてしまったので、
このミスを繰り返さないためにやり方を書きます。

参考)
http://developer.android.com/tools/publishing/app-signing.html

まず署名を作ります。


 keytool -genkey -v -keystore my-release-key.keystore
-alias alias_name -keyalg RSA -keysize 2048 -validity 10000

あとは、

ant.propertiesに


key.store=my-release-key.keystore
key.alias=alias_name

を記述。key.storeは相対パスなので注意。

ant release

で、bin/MainActivity-release.apkができる。(パスワードを2回聞かれます)
このやり方なら署名とzipalignもやってくれるので楽。

不正な署名でアップロードしてしまったら二度となおせないので、
パッケージ名を変えて作りなおすしかない。

2012年7月26日木曜日

android版rxconsole

みなさん、rxconsole使っていますか?
ROSのログを表示する便利ツールです。

で、Android版rxconsoleを作ってみました。

完成度の高いロボットは使うのにPCを必要としない一方で、
ちょっとした状態監視にlogを見たい、というコアな要求に答えてくれる
アプリです。

https://play.google.com/store/apps/details?id=com.ogutti.ros.android.rxconsole



まあ、sshでロボットにログインすればいいんですけど、エレガントじゃないですよね〜。

まだフィルタリング機能とか一部機能が足りないと思いますが、一応実用的なのではとおもいます。

是非使っていただきフィードバックをお願いします。

2012年7月14日土曜日

android_coreのインストール&ビルド

rosjavaの入門をすっとばして、android_coreのインストールを見てみます。

原典:http://docs.rosjava.googlecode.com/hg/android_core/html/index.html

1)ソースコードの入手

まず以下の2つが必要なのでイントールしましょう。


すでにインストールしている人はAndroid SKDを最新にアップデートしておきましょう(必須です。)

あとはroswsでインストールします。


roscd
rosws merge http://android.rosjava.googlecode.com/hg/.rosinstall
rosws update
source setup.bash

2)ビルド

android_coreが必要とするgoogleパッケージをビルドして、その後、メッセージをアップデートするためrosjava_messagesをビルドします。

roscd
cd google
./gradlew install

roscd rosjava_benchmarks
../gradlew install


roscd rosjava_messages
../gradlew install

で、最後にandroid_coreをビルド。


roscd android_core
./gradlew debug


以上です。

3)サンプルの実行

androidのエミュレータを上げた状態で、

roscd android_tutorial_pubsub
ant installd

とします。するとデバイスにインストールされるので、
アプリ一覧から選択して起動。
Mater選択画面では"New Master"を選択しましょう。
アプリ内でMasterが立ち上がるみたいです。




以上です。


以下は参考情報なので気にしないでいいです。

原典のドキュメント通りにやると
私の環境では以下のようなエラーがでました。なのでgoogleパッケージのビルドを追加。

    [javac] Compiling 40 source files to /home/ogutti/ros/android_core/android_h
oneycomb_mr2/bin/classes
    [javac] /home/ogutti/ros/android_core/android_honeycomb_mr2/src/org/ros/andr
oid/view/visualization/layer/CompressedBitmapLayer.java:40: パッケージ compressed_visualization_transport_msgs は存在しません。

(参考:http://answers.ros.org/question/32319/installing-rosjava-android_core-is-missing/

さらに以下のようなエラーがでました。なのでrosjava_benchmarksのビルドを追加。
(これはいらないはずだが・・・)


    [javac] /home/ogutti/ros/android_core/android_benchmarks/src/org/ros/android/android_benchmarks/MainActivity.java:25: シンボルを見つけられません。
    [javac] シンボル: クラス TransformBenchmark
    [javac] 場所    : org.ros.rosjava_benchmarks の パッケージ
    [javac] import org.ros.rosjava_benchmarks.TransformBenchmark;
    [javac]                                  ^
    [javac] /home/ogutti/ros/android_core/android_benchmarks/src/org/ros/android/android_benchmarks/MainActivity.java:61: シンボルを見つけられません。
    [javac] シンボル: クラス TransformBenchmark
    [javac] 場所    : org.ros.android.android_benchmarks.MainActivity の クラス
    [javac]     nodeMainExecutor.execute(new TransformBenchmark(), nodeConfiguration);


さらに:android_benchmarksで以下のようなエラーがたくさんでました。これはAndroid SDKをアップデートしました。

       [dx] UNEXPECTED TOP-LEVEL EXCEPTION:
       [dx] java.lang.IllegalArgumentException: already added: Lorg/apache/xmlrp
c/XmlRpcRequestConfig;....



さらにandroid_tutorial_hokuyoで失敗。SDKアップデート後にcleanしていなかったので、
gradlew cleanして再ビルドしたら直りました。

2012年3月22日木曜日

Pandaboard ESでGPIOからLED制御

組み込みAndroid Blogへようこそ。
Pandaboard ESというボードにAndroid4.0.1を載せて遊んでいます。

こちらのサイトを参考にさせてもらってインストールできました。

で、このAndroidからARMのGPIOにアクセスしてLEDをつけたり消したりする
アプリを作ってみました。
アプリの見た目はこんな感じ。ToggleボタンでLEDをOn/Offできます。

ソースはこちらから。githubをいまさらはじめてみました(登録したのは2年前)。

PIN配置は下の写真を参考に。
ただし、これは普通には実行できません。アクセス権がないので。
USBでPCとつないだ状態で、
$ adb shell
# echo 32 > /sys/class/gpio/export
# chmod 666 /sys/devices/virtual/gpio/gpio32/direction
をした後にこのアプリを使えます。(GPIO32の場合)

大画面での実行の様子。



AndroidはiPhoneと違って、パーミッションさえあれば、いろいろできてしまって面白いです。中身は完全にARMで動くLinuxなので、やりやすいですし。

2012年2月25日土曜日

ApplicationsPlatform対応Teleopアプリを作ってみた

前々回作ったAndroid デバイスを傾けるとルンバが動くというアプリを
前回紹介したApplicationsPlatformに対応させました。
というか別アプリで登録しました。
(こっちはApplicationsPlatformに対応したロボットがないと動かないので。)

アイコンも少しやる気をだしました。

以下スクリーンショット。

App Chooserでのアプリ選択画面

センサ初期化待ち

傾けた時の画面。ドロイド君が傾くよ。
ダウンロードはこちらから。(要App Chooser)
https://market.android.com/details?id=com.ogutti.ros.android.roomba_app

前回のアプリもRoomba Controllerといいながら、

「Roombaを所有し、ROIでルンバをPCから操作するデバイス(FRISK Roomba等)を所持し、すでにROSでRoombaを操作している人で、Androidデバイスを所有している」だけが使えるRoombaコントローラでした。
(全世界推定ユーザー数15人)

もしくは
「ROSで動くロボットを所有し、Androidデバイスを所有している人」が使える
ロボットコントローラでした。
(こっちは研究者いれれば結構いるかも)


今回はApplicationsPlatformに対応したロボットを持っている人用のAndroidアプリです。Turtlebot、PR2をお持ちのあなた!是非お試しください。

使い方は以下を参照ください。
http://ros.org/wiki/otl_android_roomba_app/

まず必要なスタックのソースをダウンロード。(ROS_PACKAGE_PATH

svn checkout https://otl-ros-pkg.googlecode.com/svn/trunk/otl_android

次にあなたのロボットの.installedファイルを編集してください。Turtlebotなら、turtlebot_bringupパッケージのmock_apps/turtlebot_apps.installedだと思います。


 - display: Tilt Teleop
   app: otl_android_roomba_app/roomba


あとはApp ChooserからTilt Teleopを選択すれば使えるはずです。
.appファイルを編集すると速度とか、cmd_velのremapとかができます。

(前々回のアプリ同様、不正なURIを指定してしまうと、強制終了させる必要が有ります。ライブラリの不具合っぽいです。もしかしたら使い方の問題かもですが。)

2012年2月24日金曜日

ApplicationsPlatformの紹介

最近、Androidでrosjavaを試していました。

WillowはさらにApplicationsPlatformというフレームワーク?を用意しています。

http://www.ros.org/wiki/ApplicationsPlatform

Over Viewを引用すると・・・

The applications platform allows users to interact with contained demos and utilities called "applications". These applications allow users to easily share and interact with demos and software.
ということでよく分からないですね。

どうやら、Android側からアプリケーションを選択して、ロボットを動かす仕組みのようです。
構成要素は以下のようです。

  • Androidのある特定タスク用専用アプリ
  • そのアプリに必要なロボット側のソフトの起動
  • そのアプリのロボット依存部の設定
確かにROSではノードをずらーっと起動するけど、いろんなことやらせるときに、
いらないノードとか、競合しちゃうノードとかあると思うので、どうするのかな〜?
って思ったことがありました。

この仕組みを使うと、Android側でやりたいことを決めると、ロボット側が必要なノードを上げてくれる、アプリが終われば戻してくれる、ということができるようです。
概要は↓に。

赤く囲った部分が自作するAndroidアプリで、app_chooserから呼ばれます。
また、このアプリに必要なノードをこのアプリから立ち上げることができます。(青囲み)

デモするためにコンソールを開く必要がなくなり、さっと、Android携帯からロボットソフト立ち上げから、インタフェースとして利用するところまで一発でできる、スマートな仕組みだと思いました。

2012年2月17日金曜日

ROS Android アプリ公開してみた

ルンバ操縦用に作ってみたrosjavaで作ったAndroidアプリをのりで公開してみました。
実用性はほとんどありません。(自己満足公開です)

https://market.android.com/details?id=com.ogutti.ros.android.roomba


最初のROS_MASTER_URIの設定間違えると強制終了するしかないようなので、
注意してください。

Willowが作ったやつが結構公開されていますね。
Android 3用が多いので、2.3でも動くというのが売りですかね・・・・。

2012年2月4日土曜日

Android + rosjava でRoombaを操作

当初の目標だったAndroidでのルンバ操作アプリが一応できました。

Androidで端末の傾きセンサの値を取得し、それを速度に変換し、rosjavaを使ってtopicとして出力します。



おまけで掃除機能のOn/Off、ドックへの合体指示も出せるようにボタンをつけました。
ただし、この機能はotl_roombaパッケージのroomba_twist_node.pyを想定しています。
システム図は↓のような感じです。
Roomba制御のためにPCを経由しています。本当はAndroidからBluetoothで直接Roombaを操作可能なので、実はこのアプリはかなり冗長です。

でもこのノードは/cmd_vel (geometry_msgs/Twist)を出力するので、制御対象がルンバだろうが、PR2だろうが、動かすことができるというメリットもあります。


シミュレータでの動作画面は↓のようになっています。
スライダで最大動作速度を変えたり、ボタンでクリーナーのOn/Off等ができます。
一番上のでかいロゴに意味はありません。


リポジトリに上げましたが、
ソースもさらしておきます。まずはルンバ操作用クラス


/**
 * @license New BSD License
 * 
 */
package com.ogutti.ros.android.roomba;

import org.ros.message.geometry_msgs.Twist;
import org.ros.message.std_msgs.Bool;

import org.ros.namespace.GraphName;
import org.ros.node.NodeMain;
import org.ros.node.topic.Publisher;
import org.ros.node.Node;

/**
 * class for Controlling a roomba by Twist msg
 * 
 */
public class RoombaControllerNode implements NodeMain {
 private Publisher<Twist> velPublisher;
 private Publisher<Bool> cleanPublisher;
 private Publisher<Bool> dockPublisher;

 @Override
 public void onShutdown(Node arg0) {
 }

 @Override
 public void onShutdownComplete(Node arg0) {
 }

 @Override
 public void onStart(Node node) {
  velPublisher = node.newPublisher("/cmd_vel", "geometry_msgs/Twist");
  cleanPublisher = node.newPublisher("/roomba/clean", "std_msgs/Bool");
  dockPublisher = node.newPublisher("/roomba/dock", "std_msgs/Bool");

 }

 @Override
 public GraphName getDefaultNodeName() {
  return new GraphName("roomba_controller");
 }

 /**
  * start/stop cleaning motor
  * @param isOn if true start cleaning, false stop.
  */
 public void publishClean(boolean isOn) {
  if (cleanPublisher != null) {
   Bool msg = new Bool();
   msg.data = isOn;
   cleanPublisher.publish(msg);
  }
 }

 /**
  * Publish roomba's velocity (Vx, Vtheta)
  * @param linearX twist.linear.x forward speed [m/s]
  * @param angularZ twist.angular.z rotational speed [rad/s]
  */
 public void publishVelocity(double linearX, double angularZ) {
  if (velPublisher != null) {
   Twist vel = new Twist();
   vel.linear.x = linearX;
   vel.angular.z = angularZ;
   velPublisher.publish(vel);
  }
 }

 /**
  * start docking
  */
 public void publishDock() {
  if (dockPublisher != null) {
   Bool msg = new Bool();
   msg.data = true;
   dockPublisher.publish(msg);
  }
 }
}
つぎはメインのActivityのクラス
/**
 * @license New BSD License
 */

package com.ogutti.ros.android.roomba;

import java.text.DecimalFormat;
import java.util.List;
import android.os.Bundle;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.ToggleButton;

import org.ros.address.InetAddressFactory;
import org.ros.android.MessageCallable;
import org.ros.android.RosActivity;
import org.ros.android.views.RosTextView;
import org.ros.node.NodeConfiguration;
import org.ros.node.NodeMainExecutor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import com.ogutti.ros.android.roomba.R;
import org.ros.message.geometry_msgs.Twist;

/**
 * MainActivity of this App (roomba controller)
 * 
 */
public class MainActivity extends RosActivity implements SensorEventListener {

 private RosTextView<Twist> rosTextView;
 private SensorManager sensorManager;
 private RoombaControllerNode controllerNode;
 
 private static final double LINEAR_VELOCITY_RATE  = 0.05;
 private static final double ANGULAR_VELOCITY_RATE = 0.1;

 /**
  * 1.0 means max speed, 0.0 means stop always.
  */
 private double speedRate;

 public MainActivity() {
  super("Roomba Controller", "Roomba Controller");
  speedRate = 0.5;
 }

 @SuppressWarnings("unchecked")
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
  rosTextView = (RosTextView<Twist>) findViewById(R.id.text);
  rosTextView.setTopicName("/cmd_vel");
  rosTextView.setMessageType("geometry_msgs/Twist");
  rosTextView
    .setMessageToStringCallable(new MessageCallable<String, Twist>() {
     @Override
     public String call(Twist message) {
      DecimalFormat df = new DecimalFormat();
      df.setMaximumFractionDigits(2);

      return "vel_x:\n" + df.format(message.linear.x) + "\n"
        + "vel_theta:\n" + df.format(message.angular.z);
     }
    });
 }

 @Override
 protected void init(NodeMainExecutor nodeMainExecutor) {
  // create ROS nodes
  controllerNode = new RoombaControllerNode();
  NodeConfiguration nodeConfiguration = NodeConfiguration
    .newPublic(InetAddressFactory.newNonLoopback().getHostName());
  nodeConfiguration.setMasterUri(this.getMasterUri());
  nodeMainExecutor.execute(controllerNode, nodeConfiguration);
  nodeMainExecutor.execute(rosTextView, nodeConfiguration);

  // set callback for accelerometer
  List<Sensor> sensors = sensorManager
    .getSensorList(Sensor.TYPE_ACCELEROMETER);
  if (sensors.size() > 0) {
   Sensor accelerometer = sensors.get(0);
   sensorManager.registerListener(this, accelerometer,
     SensorManager.SENSOR_DELAY_FASTEST);
  } else {
   android.util.Log.v("MainActivity", "NOT found sensor!");
  }
  
  // set toggle button's callback
  ToggleButton tb = (ToggleButton) findViewById(R.id.toggleButton1);
  tb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
   @Override
   public void onCheckedChanged(CompoundButton buttonView,
     boolean isChecked) {
    controllerNode.publishClean(isChecked);
   }
  });

  // set seekbar callback. 
  SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar1);
  final TextView tv1 = (TextView) findViewById(R.id.textView1);
  seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
   public void onProgressChanged(SeekBar seekBar, int progress,
     boolean fromUser) {
    tv1.setText("Speed:" + progress + "%");
    speedRate = progress * 0.01f;
   }

   @Override
   public void onStartTrackingTouch(SeekBar seekBar) {
   }

   @Override
   public void onStopTrackingTouch(SeekBar seekBar) {
   }
  });
  Button dockButton = (Button) findViewById(R.id.button1);
  dockButton.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(android.view.View v) {
    controllerNode.publishDock();
   }
  });

 }

 @Override
 protected void onResume() {
  super.onResume();

 }

 @Override
 protected void onStop() {
  super.onStop();
  sensorManager.unregisterListener(this);
 }

 @Override
 public void onAccuracyChanged(Sensor sensor, int accuracy) {
 }

 /**
  * callback of sensor change(accelerometer)
  */
 @Override
 public void onSensorChanged(SensorEvent event) {
  if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
   double linearX = event.values[1] * -LINEAR_VELOCITY_RATE * speedRate;
   double angularZ = event.values[0] * ANGULAR_VELOCITY_RATE * speedRate;
   if (Math.abs(linearX) < LINEAR_VELOCITY_RATE) {
    linearX = 0.0d;
   }
   if (Math.abs(angularZ) < ANGULAR_VELOCITY_RATE) {
    angularZ = 0.0d;
   }
   controllerNode.publishVelocity(linearX, angularZ);
  }
 }
}
ちょっと長いですが以上になります。
Androidアプリは作るのが結構簡単なのでチャレンジしてみてはどうでしょうか。

2012年1月21日土曜日

rosjavaをandroidで動かす(その2:カメラチュートリアル)

前回はandroid_tutorial_pubsubパッケージを試してみましたが、
今回はandroid_tutorial_cameraをやってみました。

とりあえずビデオ取りました。
android上でサンプルを実行し、PC上でimage_viewを実行して画像を表示してみました。
そんだけです。

動画はiPhoneで取りました。

2012年1月20日金曜日

rosjavaをandroidで動かす(その1)

この情報は古いので↓を参考にしてください。
http://ros-robot.blogspot.jp/2012/07/androidcore.html


==========古い情報=============

今回はrosjavaをAndroidで動かします。
ビルドするところまでやります。

例のごとくrosjavaは開発が盛んなのですでに情報が古くなっている可能性が高いことをご了承ください。

まずはソースコードを入手します。

hg clone https://android.rosjava.googlecode.com/hg/rosjava_android --insecure

AndroidSDKは↓からダウンロードできます。
http://developer.android.com/sdk/index.html

tar zxvf Downloads/android-sdk_r16-linux.tgz
などとして解凍しましょう。


さらにandroid-sdkのandroidコマンドにPATHを通します。
export PATH=$PATH:~/android-sdk-linux/tools

そしてビルドします。

roscd android_tutorial_pubsub
rosmake

そしたら、eclipseでこのandroid_tutorial_pubsubフォルダをimportします。


↓が参考になると思います。
http://ros.org/wiki/rosjava/Build/Eclipse

あとはandroid_gingerbreadパッケージもimportすればeclipse上でビルドできると思います。

注:以下Android開発環境が整っているものとして書きます。
VM等は最後に載せたサイトなどを参考に構築してください。

android_tutorial_pubsubプロジェクトを右クリックして、
Run As -> Android Applicationを選択します。

エミュレータでの実行画面を載せておきます。


上のテキストボックスにはROS_MASTER_URIを書くみたいです。
ですが、このサンプルはprivate(外と繋げない)なので有効じゃないと思います。
とりあえずこのままで。

Hello world!+数字が表示されます。

左上のアイコンがかっこいいですね!

Android開発はいろんなページがあるので、そちらで勉強しておく必要があると思います。

私はここを参考にしました。
http://thinkit.co.jp/book/2010/05/06/1536

こちらにはもっといろいろまとまっています。
http://d.hatena.ne.jp/moto_maka/20110117/1295205374


このサンプルはPrivateなので、残念ながら外からつなげることができません。

次回はソースを見て、外とつなげられるようにしてみます。