ツタンラーメンの忘備録

プログラミングや精神疾患、ラーメンについて書いていきます。たぶん。

初心者がopenframeworksでclassを使う時の話

openframeworksでclassを使いたいことが当然あるわけだが、そんなときは下の記事に従って作っていけばいい。

openFrameworks.jp


ただちょっと賢くなった気がして、ヘッダファイルの中で一部をprivateに入れると動かなくなります。上の例だと

class ofBall{
  private:
    ofBall();
};

当たり前ですね。
ちなみに新しく作ったclassの中で

w = ofGetWidth();

とやっても1024が代入されます。
おそらく初期値なのではないかと思います。これこまった…。

node-oscでopenframeworksと通信した

iOSとnode.jsからデスクトップのopenframeworksにosc通信しました。普通に何の特別なことはなくて、資料も無限に転がっているのでここで書くこともないんだけど、前に少し気になったのでメモがてらに。

receiver1.setup(PORT);
receiver2.setup(PORT);

みたいに別のところからくるデータを同じポートで受信すると、うまくいかない。少なくともうまくいかなかった。

あと
node-oscにおいて、一つのアドレスに対して複数の数値を送るには

oscclient.send('/node/raw', this.raw.x, this.raw.y, this.raw.z);

みたくする。

しかし、node-oscは三行でデータが送れて便利だ。というかosc通信が便利。

johnny-fiveでコンパスの生データを得る(get raw data of compass)

普通には得られなさそうだったので、ライブラリの方を書き換えました。
今本家にはissueしています。できたのに、自分の調べが甘いだけだったら申し訳ないのだけど…。

とりあえず、johhy-fiveとは
node.jsでArduinoを制御できるライブラリです。
github.com
これね。使い方は簡単なんだけどarduinoに慣れていると、けっこう使い方にとまどうかもしれません。普通にarduinoでやればいい内容だったんだけど、ちょっと試してみたくなったので。

で、使い方は他のところのほうが詳しいので省略します。
JavaScriptとArduinoではじめるIoT入門 〜Johnny-Fiveを使ってみる〜 | 電子工作部
node.jsとjohnny-fiveを使って、JavaScriptでarduinoを操作してみる - 株式会社ネクスト エンジニアBlog
Johnny-Fiveでマイコン制御21 - コンパス・ジャイロ・GPS - 電子部
かなり簡単。

使い方は

npm install johnny-five

で使える。

どんなコードを書いたかというと

var five = require('johnny-five');
var board = new five.Board();

board.on("ready", function(){
   var magnetometer = new five.Magnetometer({
     controller: "HMC5883L",
   });
   magnetometer.on("data", function(){
     console.log('heading', Math.floor(this.heading));
     console.log(this.raw);
   });
});

Magnetometer使わなくてもCompassを使えるし、そっちの方がスッキリするかもしれない。
とにかく

console.log(this.raw)

はundefindedとなる。悲しい。公式には得られそうな感じに書いてあるのに。
で、かなり調べた挙句、結局得られなさそうだなと思ったので、ライブラリ(モジュール)を書き換える。
currentDirectory\node_modules\johnny-five\lib

compass.js
を開いて

    heading: {
      get: function() {
        return this.toScaledHeading(raw);
      }
    }

こんな感じのが真ん中より下の方に有る。
それの上くらいに

      raw: {
          get: function () {
              return raw;
          }
      },

これを挿入する。

そうすると得られるようになる。
やったー!

node.jsとnode-twitterでオウム返しボットを作る

この記事は16/12/27に書かれています。
いろいろ調べたんだけど記事が古くて、若干そのままだと動かないので。

tips.hecomi.com
基本的にはこの記事のコード。

var twitter = require('twitter');
const BOT_ID = 'MY_BOT_ID';

var bot = new twitter({
	consumer_key        : 'xxxxxxxxxx',
	consumer_secret     : 'xxxxxxxxxx',
	access_token_key    : 'xxxxxxxxxx',
	access_token_secret : 'xxxxxxxxxx'
});

bot.stream('user', function(stream) {
	stream.on('data', function(data) {
		var id        = ('user' in data && 'screen_name' in data.user) ? data.user.screen_name : null;
		var text      = ('text' in data) ? data.text.replace(new RegExp('^@' + BOT_ID + ' '), '') : '';
		var ifMention = ('in_reply_to_user_id' in data) ? (data.in_reply_to_user_id !== null) : false;

		if (!ifMention || id == BOT_ID) return;
		var msg = {
                  status: '@' + id + ' ' + text,
                }; //ここがちょっと違う
		bot.post('statuses/update', msg , function (error, tweet, response) { //ここもちょっと違う
			console.log(tweet);
		});
	});
});

だいたいそのままで動くのですが、ちょっと違っているので、メモとして。

node.jsでPromiseを勉強しながら自分の過去ツイートを削除した(node-twitter)

Promiseはけっこうわかりづらいと思う(独断)のだけど、node.jsにおいて使えないとけっこうつらいです。つらいです。つらいです。

Promiseがどういうものでどういうふうに使うかというと下の記事がわかりやすいです。
qiita.com

むっちゃ雑に説明するとnode.js(javascript)における同期処理を非同期っぽく使いたいときに見た目がきれいになるものです。(独断)

ここでPromiseを解説しても仕方ないというかできないので、どういうことをしたくて、どういうふうにしたら動いたか軽く書いておきます。

twitter APIを叩いて

  1. 自分のアカウントのidを調べて
  2. 自分のツイートを辿って
  3. 全削除

したかった。でも、node.jsはツイッターのデータの取得を待っている間に次の処理が始まるんですよね。で、Promise。

大雑把に下のようなコードを描いています。例外処理とかきちんとしてくださいね。
node v6.2.1
npm v3.9.3
twitter v1.7.0

var Twitter = require('twitter');

var twitter = new Twitter({
    consumer_key: process.env.CONSUMER_KEY,
    consumer_secret: process.env.CONSUMER_SECRET,
    access_token_key: process.env.OAUTH_TOKEN,
    access_token_secret: process.env.OAUTH_TOKEN_SECRET,
});

var get_screen_name = function(){
  return new Promise(function(resolve, reject){
    twitter.get('account/settings', function(error, data, res){
      if(!error){
        resolve(data.screen_name);
      }
    });
  });
};

var get_tweets = function(screen_name){
  return new Promise(function(resolve, reject){
    var params = {
      count: 100,
      screen_name: screen_name,
    };
    twitter.get('statuses/user_timeline', params, function (error, tweets, response) {
      if (!error) {
        resolve(tweets);
      }
    });
  });
};

var delete_tweets = function(tweets){
  var promises = [];
  for (var i = 0; i < tweets.length; i++) {
    promises.push(delete_tweet(tweets[i]));
  }
  Promise.all(promises)
    .then(function (results) {
      console.log(results);
  });
};

var delete_tweet = function(tweet){
  return new Promise(function(resolve, reject){
    twitter.post('statuses/destroy', {id: tweet.id_str}, function(error, data){
      if(!error){
        resolve(data);
      }
    });
  });
};

get_screen_name()
  .then(get_tweets)
  .then(delete_tweets);

ツイートを一つずつdelete_tweetに放り込むんだけど、普通に

var delete_tweets = function(tweets){
  for(var i = 0; i < tweets.length; i++){
    delete_tweet(tweets[i]);
  }
};

とかやると同期非同期問題で順番がずれて死ぬ。
参考にしたのは下の記事
qiita.com

あとtwitter APIの使い方がいくつもなんかうまくいかなかった。
まずしばらく自分のタイムラインを取得する方法を探したのだけど、結果、自分のscreen_name(一般的に言えば@を抜いたユーザid)を取得後、そのidのツイートを遡るということをした。

あと意外と詰まったのがツイートのidの取得方法。
普通に

tweet.id;

で取れるんだけど、オーバーフローする?らしく全桁取得できていないっぽい。普通に

tweet.id_str;

にすれば文字列として出てくるので、処理できました。
あとこれはnode-twitterの仕様なのだけど
POST statuses/destroy/:id — Twitter Developers
ここを見て

    twitter.post('statuses/destroy/:id', {id: tweet.id_str}, function(error, data){

    });

ってしていたのだけど、これじゃ動かないです。

うーん…node.jsでtwitter弄る人が少ないせいか資料が少ない…。

openframeworksでxmlファイルがどこに消えたかわからなくなった

openframeworks(iOS)でxmlファイルがどこにあるかわからず、困った。
bin/data内にmySettings.xmlってファイルを作ると読み込めるんだけど、保存できない。おそらくtxtファイルも同じだろうと思う。結論としてはサンプル(example/ios/xmlSettingsExample)を読めということに尽きる(僕はサンプルを読むのが嫌いなのでだいぶ遠回りしました)。
ちなみに
openframeworks(iOS) v0.9.6
Xcode version8.1
iOS 10.0.2

ただ、サンプルが長くて読むのがめんどくさいので必要最小限で書く。
ヘッダファイルで

#include "ofxXmlSettings.h"
//省略

class ofApp:public ofxiOSApp{
  //省略
  ofxXmlSettings XML;
};
void ofApp:setup(){
  //省略
  if(XML.loadFile(ofxiOSGetDocumentDirectory() + "mySettings.xml")){
    cout<<"loaded from documents folder"<<endl;
  }else if(XML.loadFile("mySettings.xml")){
    cout<<"loaded from data folder"<<endl;
  }else{
    cout<<"unable to load it"<<endl;
  } //このへんはサンプルまんま
  host = XML.getValue("HOST", "255.26.?.45"); //getValue(検索したいタグ, 見つからなかったときの初期値)
}

//省略

void ofApp:touchUp(ofTouchEventArgs & touch){
  XML.setValue("HOST", host);
  XML.saveFile(ofxiOSGetDocumentDirectory() + "mySettings.xml");
}

こんな感じである。

raspberry pi 3の初期セットアップ

初心者がらずぱいを使おうというのが間違っています?が、らずぱいをノリで買ったので、初期セットアップの話をします。
必要なものは他のサイトでさんざん書かれているので省略として、らずぱいには導入できるOSが何種類か有ります。どれを使おうか、初心者は悩むと思います。
資料が多そうなraspbianにしましょう。でそうすると二種類あります。

  • Raspbian Jessie with PIXEL
  • Raspbian Jessie Lite

上を選んだらものすごくインストールに時間がかかって失敗したから下を選びました。
黒い画面に白い文字がいっぱいでした。
意味がわかりませんでした。


結論、GUIが最初から使える
Raspbian Jessie with PIXELを選びましょう
下でもGUIモードみたいなのあるらしいんだけど失敗しました。