ラベル プログラミング の投稿を表示しています。 すべての投稿を表示
ラベル プログラミング の投稿を表示しています。 すべての投稿を表示

9月 15, 2022

atomcam_toolsを用いたWebブラウザでのAtom cam画像取得

Atomcamは、安価に手に入り、小型でかつ屋外使用も可能なため非常に使いやすいネットワークカメラです。
ただ、純正のアプリがよく落ちるのと、APIなどが公開されているわけではないので、凝ったことをしようとするとびみょーに使い勝手が良くない。。
そこで、有志の方々(mnakada氏、bakueikozo氏)が開発してくれたatomcam_toolsを使って、まずはWebブラウザ上で映像確認を行えるようにします

Grafanaのグラフで第2軸(Right Y Axis)を追加する方法

Grafanaの第2軸(Right Y Axis)を設定する方法が分かりづらかったため、備忘録として記載しておきます。

6月 21, 2022

Nature Remo Eを使った電力使用状況の取得

自家消費している電力や売電状況を確認する方法はいくつかあるが、Nature Remo Eを使用して手っ取り早く情報を取得する。

6月 16, 2022

pythonを用いたinfluxdbへのデータ保存

pythonで実装したプログラムで取得したデータをinfluxdbに保存する
こちらを参考に実装

Bluetooth BLEによるSwitchbotのセンサー情報取得

Bluetooth BLEに対応した各種センサーがSwitchbotから出ているので、それらの情報を取得しスマートホームの制御に用いたい。
Switchbotの純正アプリでもトリガー&アクションを設定できるが、Switchbot製品しか設定できないため、自分で実装しあとでNode-redに接続する。

6月 15, 2022

Node-redによるMeross plugの制御

IFTTTなどを用いずに、node-red-contrib-merossを使用してNode-redでMeross Smart Plugを直接制御する。

6月 09, 2022

node.jsを用いたinfluxdbへのデータ保存

node.jsで実装したプログラムで取得したデータをinfluxdbに保存する こちらを参考に実装

ライブラリのインストール

$ npm install influx

node.js

ライブラリの読み込みと、初期設定を行う

const Influx = require('influx')
const influxAircon = new Influx.InfluxDB({
    host: '192.168.***.***',
    database: 'homedata',
    schema: [
        {
            measurement: 'echonet-Aircon',
            tags: [
                'addr',
                'place'
            ],
            fields: {
                status: Influx.FieldType.STRING,
                mode: Influx.FieldType.STRING,
                modeNum: Influx.FieldType.INTEGER,
                setTemp: Influx.FieldType.INTEGER,
                measureHumi: Influx.FieldType.INTEGER,
                measureTemp: Influx.FieldType.INTEGER,
                measureOutdoorTemp: Influx.FieldType.INTEGER
			}
        }
    ]
})

データの書き込み

influxAircon.writePoints([
			{
				measurement: 'echonet-aircon',
				tags: { addr: address, place: "aircon" },
				fields: {
					status: vStatus,
					mode: vMode,
					modeNum: vModeNum,
					setTemp: vSetTemp,
					measureHumi: vMeasureHumi,
					measureTemp: vMeasureTemp,
					measureOutdoorTemp: vMeasureOutdoorTemp
				}
			} 
		]).catch(err => {
			console.error(`Error saving data to InfluxDB! ${err.stack}`)
		})

ECHONET liteを用いた太陽光発電&蓄電池&エコキュートの情報取得

node-echonet-liteを用いて太陽光発電、蓄電池、エコキュートから情報を取得する
公開されているサンプルを参考に、Node.jsで実装
詳細やエアコンからの情報取得についてはこちらを参照

太陽光発電

//Solar
function getOperationStatus_Solar(address, eoj) {
	var esv = 'Get';
	var prop = [
		{ 'epc': 0x80, 'edt': null }, // ON/OFF
		{ 'epc': 0xE0, 'edt': null } // 発電量
	];
	el.send(address, eoj, esv, prop, (err, res) => {
		console.log('[Solar] @' + address);
		console.log('  Err : ' + err);
		console.log('  ESV : ' + res['message']['esv']);
		var vStatus = '';
		var vWatt = '';
		for (let element of res['message']['prop']){
			//console.dir(element);
			var epc = element['epc'];
			var edt = element['edt'];
			if (epc === 0x80) {
				vStatus = (edt['status'] ? 'on' : 'off');
				//saveToFile(dataDIR+"/solar@"+address+"_Power",desc);
				console.log('  Power : ' + vStatus);
			}else if (epc === 0xE0) {
				vWatt = element['buffer'][0]*256 + element['buffer'][1];
				//saveToFile(dataDIR+"/solar@"+address+"_Generate",num);
				console.log('  Electric generate : ' + vWatt + '[W]');
			} else{
				console.dir(element);
			}
		}
	});
	getOperationStatus_Battery(address);
}

蓄電池

//Battery
function getOperationStatus_Battery(address) {
	var esv = 'Get';
	var eoj = new Array(0x2,0x7d,1);
	var prop = [
		{ 'epc': 0x80, 'edt': null }, // ON/OFF
		{ 'epc': 0xA0, 'edt': null }, //
		{ 'epc': 0xA1, 'edt': null }, //
		{ 'epc': 0xA2, 'edt': null }, //
		{ 'epc': 0xA3, 'edt': null }, //
		{ 'epc': 0xA4, 'edt': null }, //
		{ 'epc': 0xA5, 'edt': null }, //
		{ 'epc': 0xCF, 'edt': null }, //
		{ 'epc': 0xD3, 'edt': null }, //
		{ 'epc': 0xE4, 'edt': null }, //
		{ 'epc': 0xE5, 'edt': null }  //
	];
	el.send(address, eoj, esv, prop, (err, res) => {
		console.log('[Battery] @' + address);
		console.log('  Err : ' + err);
		console.log('  ESV : ' + res['message']['esv']);
		var vStatus = "";
		var vEffectiveCapacity_charge = "";
		var vEffectiveCapacity_disCharge = "";
		var vChargeableCapacity = "";
		var vDischargeableCapacity = "";
		var vCapacity_charge = "";
		var vCapacity_discharge = "";
		var vOutput = "";
		var vMode = "";
		var vBatteryLevel = "";
		var vDeterioration = "";
		for (let element of res['message']['prop']){
			//console.dir(element);
			var epc = element['epc'];
			var edt = element['edt'];
			if (epc === 0x80) {
				vStatus = (edt['status'] ? 'on' : 'off');
				//saveToFile(dataDIR+"/battery@"+address+"_Power",desc);
				console.log('  Power : ' + vStatus);
			} else if (epc === 0xA0) {
				var num0 = element['buffer'][0]<<24;
				var num1 = element['buffer'][1]<<16;
				var num2 = element['buffer'][2]<<8;
				var num3 = element['buffer'][3];
				vEffectiveCapacity_charge = num0 + num1 + num2 + num3;
				//saveToFile(dataDIR+"/battery@"+address+"_EffectiveCapacity_charge",num);
				console.log('  AC実効容量(充電) : ' + vEffectiveCapacity_charge + '[Wh]');
			} else if (epc === 0xA1) {
				var num0 = element['buffer'][0]<<24;
				var num1 = element['buffer'][1]<<16;
				var num2 = element['buffer'][2]<<8;
				var num3 = element['buffer'][3];
				vEffectiveCapacity_disCharge = num0 + num1 + num2 + num3;
				//saveToFile(dataDIR+"/battery@"+address+"_EffectiveCapacity_discharge",num);
				console.log('  AC実効容量(放電) : ' + vEffectiveCapacity_disCharge + '[Wh]');
			} else if (epc === 0xA2) {
				var num0 = element['buffer'][0]<<24;
				var num1 = element['buffer'][1]<<16;
				var num2 = element['buffer'][2]<<8;
				var num3 = element['buffer'][3];
				vChargeableCapacity = num0 + num1 + num2 + num3;
				//saveToFile(dataDIR+"/battery@"+address+"_ChargeableCapacity",num);
				console.log('  AC充電可能容量 : ' + vChargeableCapacity + '[Wh]');
			} else if (epc === 0xA3) {
				var num0 = element['buffer'][0]<<24;
				var num1 = element['buffer'][1]<<16;
				var num2 = element['buffer'][2]<<8;
				var num3 = element['buffer'][3];
				vDischargeableCapacity = num0 + num1 + num2 + num3;
				//saveToFile(dataDIR+"/battery@"+address+"_DischargeableCapacity",num);
				console.log('  AC放電可能容量 : ' + vDischargeableCapacity + '[Wh]');
			} else if (epc === 0xA4) {
				var num0 = element['buffer'][0]<<24;
				var num1 = element['buffer'][1]<<16;
				var num2 = element['buffer'][2]<<8;
				var num3 = element['buffer'][3];
				vCapacity_charge = num0 + num1 + num2 + num3;
				//saveToFile(dataDIR+"/battery@"+address+"_Capacity_charge",num);
				console.log('  AC充電可能量(現時点での) : ' + vCapacity_charge + '[Wh]');
			} else if (epc === 0xA5) {
				var num0 = element['buffer'][0]<<24;
				var num1 = element['buffer'][1]<<16;
				var num2 = element['buffer'][2]<<8;
				var num3 = element['buffer'][3];
				vCapacity_discharge = num0 + num1 + num2 + num3;
				//saveToFile(dataDIR+"/battery@"+address+"_Capacity_discharge",num);
				console.log('  AC放電可能量(現時点での) : ' + vCapacity_discharge + '[Wh]');
			} else if (epc === 0xD3) {
				var num0 = element['buffer'][0]<<24;
				var num1 = element['buffer'][1]<<16;
				var num2 = element['buffer'][2]<<8;
				var num3 = element['buffer'][3];
				vOutput = num0 + num1 + num2 + num3;
				if (vOutput > 0xC4653601 ){
					vOutput = vOutput - 0x100000000a;
				}
				//saveToFile(dataDIR+"/battery@"+address+"_Output",num);
				console.log('  瞬間充放電電力計測値 : ' + vOutput + '[W]');
			} else if (epc === 0xCF) {
				vMode = element['buffer'][0];
				switch(vMode){
					case 0x41:
						vMode = "急速充電";
						break;
					case 0x42:
						vMode = "充電";
						break;
					case 0x43:
						vMode = "放電";
						break;
					case 0x44:
						vMode = "待機";
						break;
					case 0x45:
						vMode = "テスト";
						break;
					case 0x46:
						vMode = "自動";
						break;
					case 0x48:
						vMode = "再起動";
						break;
					case 0x49:
						vMode = "実効容量再計算処理";
						break;
					case 0x40:
						vMode = "その他";
						break;
					default:
				}
				//saveToFile(dataDIR+"/battery@"+address+"_Mode",desc);
				console.log('  Mode : ' + vMode);
			} else if (epc === 0xE4) {
				vBatteryLevel = element['buffer'][0];
				//saveToFile(dataDIR+"/battery@"+address+"_BatteryLevel",desc);
				console.log('  蓄電池残量 : ' + vBatteryLevel + "[%]");
			} else if (epc === 0xE5) {
				vDeterioration = element['buffer'][0];
				//saveToFile(dataDIR+"/battery@"+address+"_Deterioration",desc);
				console.log('  劣化状態 : ' + vDeterioration + "[%]");
			} else{
				console.dir(element);
			}
		}
	});
}

エコキュート

//Ecocute
function getOperationStatus_EcoCute(address, eoj) {
	var esv = 'Get';
	var prop = [
		{ 'epc': 0x80, 'edt': null }, // ON/OFF
		{ 'epc': 0xB2, 'edt': null }, // 炊き上げ中
		{ 'epc': 0xC3, 'edt': null }, // 給湯中
		{ 'epc': 0xE1, 'edt': null }  // 残湯量
	];
	el.send(address, eoj, esv, prop, (err, res) => {
		console.log('[EcoCute] @' + address);
		console.log('  Err : ' + err);
		console.log('  ESV : ' + res['message']['esv']);
		var vStatus = "";
		var vHotWaterMake = "";
		var vHotWaterOutput = "";
		var vHotWaterVolume = "";
		for (let element of res['message']['prop']){
			//console.dir(element);
			var epc = element['epc'];
			var edt = element['edt'];
			if (epc === 0x80) {
				vStatus = (edt['status'] ? 'on' : 'off');
				console.log('  Power : ' + vStatus);
				//saveToFile(dataDIR+"/ecocute@"+address+"_Power",desc);
			} else if (epc === 0xB2) {
				hotWaterMake = element['buffer'][0];
				if (vHotWaterMake === 0x41) {
					vHotWaterMake = 1;
					console.log('  Hot water : making (' + vHotWaterMake + ')');
					//saveToFile(dataDIR + "/ecocute@" + address + "_HotWaterMake", "making");
				}else if (hotWaterMake === 0x42){
					vHotWaterMake = 0;
					console.log('  Hot water : not making (' + vHotWaterMake + ')');
					//saveToFile(dataDIR + "/ecocute@" + address + "_HotWaterMake", "not making");
				}
			} else if (epc === 0xC3) {
				vHotWaterOutput = element['buffer'][0];
				if (vHotWaterOutput === 0x41) {
					vHotWaterOutput = 1;
					console.log('  Hot water : output (' + vHotWaterOutput + ')');
					//saveToFile(dataDIR + "/ecocute@" + address + "_HotWaterOutput", "output");
				}else if (vHotWaterOutput === 0x42){
					vHotWaterOutput = 0;
					console.log('  Hot water : no output (' + vHotWaterOutput + ')');
					//saveToFile(dataDIR + "/ecocute@" + address + "_HotWaterOutput", "no output");
				}
			} else if (epc === 0xE1) {
				vHotWaterVolume = element['buffer'][0]*256 + element['buffer'][1];
				console.log('  Hot water volume : ' + vHotWaterVolume + '[l]');
				//saveToFile(dataDIR + "/ecocute@" + address + "_HotWaterVolume", num);
			} else{
				console.dir(element);
			}
		}
	});
}

ECHONET liteを用いたエアコンの情報取得

node-echonet-liteを用いて対応機器から情報を取得する
公開されているサンプルを参考に、Node.jsで実装

ライブラリのインストール

$ npm install serialport
$ npm install node-echonet-lite

初期化関係

// reference : https://github.com/futomi/node-echonet-lite

// Load the node-echonet-lite module
var EchonetLite = require('node-echonet-lite');
// Create an EchonetLite object
//   The type of network layer must be passed.
var el = new EchonetLite({ 'type': 'lan' });
el.setLang('ja');

// Initialize the EchonetLite object
el.init((err) => {
	if (err) { // An error was occurred
		showErrorExit(err);
	} else { // Start to discover devices
		discoverDevices();
		setTimeout(timeOutExit, 15000);
	}
});

対応機器の特定

startDiscovery()で応答した機器のEOJを確認する
// Start to discover devices
function discoverDevices() {
	// Start to discover Echonet Lite devices
	el.startDiscovery((err, res) => {
		// Error handling
		if (err) {
			showErrorExit(err);
		}
		// Determine the type of the found device
		var device = res['device'];
		var address = device['address'];
		var eoj = device['eoj'][0];
		//console.log(eoj);
		var group_code = eoj[0]; // Class group code
		var class_code = eoj[1]; // Class code
		if (group_code === 0x01 && class_code === 0x30) {
			//el.stopDiscovery();
			getOperationStatus_AirCon(address, eoj);
		}else{
			el.getPropertyMaps(address, eoj, (err, res) => {
				console.log(address + " : " + el.getClassGroupName(group_code) + " / " + el.getClassName(group_code, class_code));
				console.log('- IP address: ' + address);
				console.log('- EOJ: ' + JSON.stringify(eoj));
				console.log('- Property Maps:')
				console.dir(res['message']['data']);
			});
		}
	});
}

情報取得

el.send()を用いて、prop内で指定したEPCに対応するデータの送信を機器に要求する。
受信したresをAPPENDIX ECHONET機器オブジェクト詳細規定に従って読み解く
// Get the operation status
function getOperationStatus_AirCon(address, eoj) {
	var esv = 'Get';
	var prop = [
		{ 'epc': 0x80, 'edt': null }, // ON/OFF
		{ 'epc': 0xB0, 'edt': null }, // Mode
		{ 'epc': 0xB3, 'edt': null }, // Set Temperature
		{ 'epc': 0xBA, 'edt': null }, // Room Humidity
		{ 'epc': 0xBB, 'edt': null }, // Room Temperature
		{ 'epc': 0xBE, 'edt': null }  // outdoor Temperature
	];
	el.send(address, eoj, esv, prop, (err, res) => {
		console.log('[Air conditioner] @' + address);
		console.log('  Err : ' + err);
		console.log('  ESV : ' + res['message']['esv']);
		var vStatus = "";
		var vMode = "";
		var vModeNum = "";
		var vSetTemp = "";
		var vMeasureHumi = "";
		var vMeasureTemp = "";
		var vMeasureOutdoorTemp = "";
		for (let element of res['message']['prop']){
			//console.dir(element);
			var epc = element['epc'];
			var edt = element['edt'];
			if (epc === 0x80) {
				vStatus = (edt['status'] ? 'on' : 'off');
				console.log('  Power : ' + vStatus);
				//saveToFile(dataDIR+"/aircon@"+address+"_Power",desc);
			} else if (epc === 0xB0) {
				vModeNum = edt['mode'];
				vMode = edt['desc'];
				console.log('  Mode : ' + vMode + '(' + vModeNum + ')');
				//saveToFile(dataDIR+"/aircon@"+address+"_Mode",desc);
				//saveToFile(dataDIR+"/aircon@"+address+"_ModeNum",num);
			} else if (epc === 0xB3) {
				vSetTemp = edt['temperature'];
				if(vSetTemp === null ){vSetTemp = 253}
				console.log('  Set temp : ' + vSetTemp + "[℃]");
				//saveToFile(dataDIR+"/aircon@"+address+"_setTemp",desc);
			} else if (epc === 0xBA) {
				vMeasureHumi = edt['humidity'];
				//if(vMeasureHumi === 253 ){vMeasureHumi = " "}
				console.log('  Measure Humi : ' + vMeasureHumi + "[%]");
				//saveToFile(dataDIR+"/aircon@"+address+"_measureHumi",desc);
			} else if (epc === 0xBB) {
				vMeasureTemp = edt['temperature'];
				console.log('  Measure temp : ' + vMeasureTemp + "[℃]");
				//saveToFile(dataDIR+"/aircon@"+address+"_measureTemp",desc);
			} else if (epc === 0xBE) {
				vMeasureOutdoorTemp = edt['temperature'];
				if(vMeasureOutdoorTemp === 126 ){vMeasureOutdoorTemp = 253}
				console.log('  Measure Outdoor temp : ' + vMeasureOutdoorTemp + "[℃]");
				//saveToFile(dataDIR+"/aircon@"+address+"_measureOutdoorTemp",desc);
			} else{
				console.dir(element)
			}
		}
		
		//el.close();
	});
}

エラー&終了処理定

// Print an error then terminate the process of this script
function showErrorExit(err) {
	console.log('[ERROR] ' + err.toString());
	el.close();
	process.exit();
}
function timeOutExit() {
	console.log('[TimeOut]');
	el.close();
	process.exit();
}

実行結果

[Air conditioner] @192.168.***.***
  Err : null
  ESV : Get_Res
  Power : on
  Mode : 送風(5)
  Set temp : 253[℃]
  Measure Humi : 70[%]
  Measure temp : 24[℃]
  Measure Outdoor temp : 19[℃]

ECHONET Liteを使ったスマートホーム&モニタの実現を目指す

ホームオートメーション界隈で、AppleやGoogleも入って進められているMatter規格が最近話題ですね。
ただ、対応製品が出てくるのは、まだまだ先になりそう&すでに出ている製品は対応しない可能性も高く、日本の住宅機器はこういった流れに乗るのが遅いイメージを持っています。。

スマートホームやIoT関連の機器を接続する製品も出てはいますが、痒いところに手が届かないため自分で実装します。
  • ・制御できる内容が限られる
  •    →Node-redに接続して自由にやりたい
  • ・制御できる製品メーカーが限られる場合がある
  •    →Google Homeなどに接続して制御したい
  • ・機器を接続しようとするとアダプタが必要になる場合がある
  •    →仕方がないけど、極力追加したくない
  • ・総じて高額になる傾向
  •    →もともと製品が持っている機能を使って実現できるなら安上がり

日本の住宅機器や家電は、ECHONET Liteという既存の規格に大抵対応しているので、それを使ってホームオートメーション&モニタの実現を目指します


ECHONET lite

ECHONET liteは2011年頃から、日本の家電メーカ主導で整備が進められた規格です。

ECHONETのサイトから抜粋(下記に添付している画像の出典もこちらです)
ECHONET Liteは、センサ類、白物家電、設備系機器など省リソースの機器をIoT化し、
  エネルギーマネジメントやリモートメンテナンスなどのサービスを実現するための通信仕様です。
  通信仕様や各機器の制御コマンドを共通化することで、マルチベンダー環境でのシステム構築を実現します。

規格の詳細は下記


プロトコル概要

ECHONET lite機器の種類ごとにクラスが定義されており、その中のプロパティを読み書きすることで、情報の取得および制御を行っている

主要な信号のフォーマットは下記で、ヘッダーの後ろに機器のクラスとプロパティがくっついている
ざっくりとしたイメージはこんな感じ
  • EOJ:オブジェクト(通信するECHONET lite対応機器)を指定
  • EPC:取得するデータを指定
  • EDT:データが入っている

ただ、これらを0から実装するのは大変なため、有志の方が作成してくれている下記のライブラリを使用します。


ライブラリ "node-echonet-lite"

node-echonet-liteのGithubで公開されていて、Node.jsをベースに実装されています。

READMEを詳細に書いて頂いているので、詳細はGithubを参照すればよいかと思います。

2月 04, 2014

Rasberry Piのコンパイル最適化のオプション

GCCのコンパイル時にCPUの最適化をするRaspberry Pi用のオプション。

以下をMakefileに追加。

CXXFLAGS=-march=armv6zk -mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp
CFLAGS=-march=armv6zk -mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp



6月 06, 2013

Raspberry PiでOpenCVを使う


関連ソフトのインストール

Raspberry PiにOpenCVをインストールします。
詳しくは過去の記事を参考にしてください。

必要なソフトのインストール!余分なものも入ってるけど気にしないっ
必要に応じて,追加でインストールしてください

$ sudo apt-get install cmake pkg-config mencoder mplayer libgtk2.0.0 libgtk2.0-dev libjpeg62 libjpeg62-dev libjpeg62-dbg libpng12-dev libpng12-0 ffmpeg libavcodec-dev libavcodec53 libavformat53 libavformat-dev libswscale-dev libswscale2 libavfilter2 libavfilter-dev libdc1394-22 libdc1394-22-dev libgstreamer0.10-0 libgstreamer0.10-dev libgstreamer0.10-cil-dev libgstreamer-plugins-base0.10-0 libgstreamer-plugins-base0.10-dev zlib1g zlib1g-dev libxine1-ffmpeg libxine1-bin libunicap2 libunicap2-dev libdc1394-utils swig libv4l-0 libv4l-dev python-numpy python-dev 

OpenCVのインストール

あとはソースをダウンロードしてきて,解答して,Makeするだけ!

$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_PYTHON_SUPPORT=ON -D BUILD_EXAMPLES=ON ../opencv-2.4.5
make -j2
sudo make install
sudo ldconfig

3月 06, 2012

Core Duo/Quad系CPUの最適化オプション メモ

Makefileに以下を追加する(引用元

CHOST =x86_64-pc-linux-gnu
CFLAGS = -march=core2 -O2 -pipe
CXXFLAGS = ${CFLAGS}

1月 11, 2012

Boost::threadの簡単な排他処理

以前にBoostを用いてスレッドを立てましたが,これまたBoostのライブラリを使って簡単にスレッドセーフを実現する方法をメモしておきます。

#include <boost/thread.hpp>
#include <boost/bind.hpp>

boost::mutex mtx;

void hoge1(int &a){
  boost::mutex::scoped_lock lock(mtx);
  for(int n=0; n<3; ++n){
    std::cout << "hoge1:" << a+n << std::endl;
  }
  std::cout << std::endl;
  return;
}

void hoge2(int &b){
  boost::mutex::scoped_lock lock(mtx);
  for(int n=0; n<3; ++n){
    std::cout << "hoge2:" << b+n << std::endl;
  }
  std::cout << std::endl;
  return;
}

int main(int argc, char **argv){
  int c = 0;
  boost::thread thr1(boost::bind(&hoge1, c));
  boost::thread thr2(boost::bind(&hoge2, c));

  thr1.join();
  thr2.join();
  return 0;
}
これを実行すると
hoge1:0
hoge1:1
hoge1:2
hoge2:0
hoge2:1
hoge2:2
という感じになってくれると思います.

boost::mutex::scoped_lockは,デストラクタでmutexをアンロックしてくれる機能を持っています.
つまり,hoge1, hoge2内で定義されているscoped_lockはそれぞれの関数を抜ける際に破棄されるのと同時にmutexを自動的にアンロックしてくれます.
なので,この場合hoge1を実行したのちにhoge2を実行する結果になります.


12月 18, 2011

Ubuntu10.04へのCUDAのインストール

NVIDIAのドライバをすべて削除してから最新のものにする

$ sudo add-apt-repository ppa:ubuntu-x-swat/x-updates
$ sudo apt-get update
$ sudo apt-get remove nvidia-*
$ sudo apt-get install nvidia-current nvidia-settings

CUDAのサイトからdevdriver, toolkit, SDKをダウンロードしてきて,ここここを参考にインストールします.

devdriverインストール時のX停止方法
$ sudo stop gdm

これでうまく止まらない場合は
$ sudo vi /etc/init.d/grub
 GRUB_CMDLINE_LINUX_DEFAULT=のところにtextを追加
$ sudo reboot


12月 09, 2011

LLVM + Clangをソースからインストール

LLVMとClangをインストールする基本的な方法
LLVMとClangのソースをここからダウンロード

両方のファイルを解凍して,Clangの方の中身をLLVMフォルダの中のtools/clang/にコピー

$ ./configure
$ make -j2
$ sudo make install

注意:makeするときにgccとg++が必要になるのでインストールしておく


11月 13, 2011

あるクラスのメンバ関数から他のメンバ関数をスレッドとして並列実行

C++でプログラムを書いているときに,クラスの中でスレッドを実行して並列処理を行いたくなった。
Boostという便利なライブラリを使って,これを実現します。

#include <boost/thread.hpp>
#include <boost/bind.hpp>
class hoge{
  private:
    thr_func(int a);
    func(){
      int b;
      boost::thread thr(boost::bind(&hoge::func, this, b); 
      thr.join();
    }
};
Boostの使い方とかはここを参照


9月 17, 2011

gccをソースからインストール

公式から適当なバージョンのgccソースを持ってくる.

これを解凍して,configureを実行するとgmpmpfrmpcが必要だ!!って怒られるので,それらもソースからインストールします.
それぞれに依存関係があるので,gmp,mpfr,mpcの順番で入れていきます.
3つとも下の手順で大丈夫です.
./configureの途中で止まった場合は,必要なファイルが足りていないので,何が足りていないのかを調べてそれをインストールしてから再度実行

$ cd 解凍したフォルダ
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig

3つともインストールが完了すると,/usr/local/include以下にgmp.h,mpfr.h,mpf2mpfr.hとmpc.hができていると思います.
これらがあればインストールは無事に完了してると思います.

次にgccをコンパイルすれば完了です.
$ cd gccのフォルダ
$ ./configure --with-gmp=/usr/local/ --with-mpfr=/usr/local/ --with-mpc=/usr/local/ --prefix=/usr/local/gcc-4.5.3
$ make
$ sudo make install
$ sudo ldconfig
$ sudo ln -s /usr/local/gcc-4.5.3/bin/gcc /usr/local/bin/gcc-4.5.3

gccのmake時にjavaが入っていないとコンパイルに失敗するので,入っていない場合はインストールする
$ sudo add-apt-repository 'deb http://archive.canonical.com/ lucid partner'
$ sudo apt-get update 
$ sudo aptitude install sun-java6-jdk  

インストール完了の確認は
$ gcc -v
で,インストールしたバージョンになっていれば大丈夫です


8月 29, 2011

OpenCV2.3.1インストール for Ubuntu10.04

OpenCVWillow Garageが開発を行っているライブラリ。
最近では,画像処理だけでなく機械学習まわりも強化されているため,ひじょーに便利なライブラリです。
私がここ最近書いたプログラムは,ほとんどがこのライブラリに依存している状態ですw


OpenCV2.3.1のインストール

関連ソフトのインストール

OpenCV2.3のバグをとった2.3.1がリリースされたし,使いたい関数もあるのでバージョンをあげるぜーー
また2.3からOpenNIをサポートしているので,kinectの距離画像とかも簡単に取れて遊びたい放題♫

まず,公式からOpenCV2.3.1.tar.bz2をダウンロード
ダウンロードしたらそれを解凍しておく。

$ tar jxvf OpenCV2.3.1.tar.bz2

次に,apt-getで必要になりそうなものをひたすらインストール(詳しくはReadme参照で
$ sudo apt-get install cheese coriander \ 
 cmake pkg-config g++ build-essential \ 
 mencoder mplayer \ 
 libgtk2.0-0 libgtk2.0-dev \ 
 libjpeg-dev libpng-dev libtiff-dev libjpeg62 libjpeg62-dev libjpeg62-dbg \ 
 ffmpeg libavcodec-dev libavcodec52 libavformat-dev libavformat52 libswscale-dev libavfilter-dev \ 
 libdc1394-22 libdc1394-22-dev \ 
 python2.6 python2.6-dev python-numpy \ 
 libtbb2 libtbb-dev \ 
 libgstreamer0.10-0 libgstreamer0.10-dev libgstreamer-plugins-base0.10-0 libgstreamer-plugins-base0.10-dev 
 
$ sudo ldconfig


cmake

次にcmakeをして,必要なパッケージが入っているかを確認する。

$ cd OpenCV2.3.1/
$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_PYTHON_SUPPORT=ON -D WITH_TBB=ON -D WITH_GTK=ON -D BUILD_EXAMPLES=ON .

cmakeを実行した際に出力されるメッセージの最後の方が以下のようなら多分大丈夫b
ほかに入れたいものがあるなら随時インストール
-- General configuration for opencv 2.3.1 =====================================
-- 
--     Built as dynamic libs?:     YES
--     Compiler:                   /usr/bin/c++
--     C++ flags (Release):          -Wall -pthread -march=i686 -ffunction-sections  -O3 -DNDEBUG  -fomit-frame-pointer -msse -msse2 -mfpmath=387 -DNDEBUG 
--     C++ flags (Debug):            -Wall -pthread -march=i686 -ffunction-sections  -g  -O0 -DDEBUG -D_DEBUG -ggdb3 
--     Linker flags (Release):
--     Linker flags (Debug):
-- 
--   GUI: 
--     GTK+ 2.x:                   YES
--     GThread:                    YES
-- 
--   Media I/O: 
--     ZLib:                       YES
--     JPEG:                       TRUE
--     PNG:                        TRUE
--     TIFF:                       TRUE
--     JPEG 2000:                  TRUE
--     OpenEXR:                    NO
--     OpenNI:                     NO
--     OpenNI PrimeSensor Modules: NO
--     XIMEA:                      NO
-- 
--   Video I/O:
--     DC1394 1.x:                 NO
--     DC1394 2.x:                 YES
--     FFMPEG:                     YES
--       codec:                    YES
--       format:                   YES
--       util:                     YES
--       swscale:                  YES
--       gentoo-style:             YES
--     GStreamer:                  YES
--     UniCap:                     NO
--     PvAPI:                      NO
--     V4L/V4L2:                   1/1
--     Xine:                       NO
-- 
--   Other third-party libraries:
--     Use IPP:                    NO
--     Use TBB:                    YES
--     Use ThreadingFramework:     NO
--     Use Cuda:                   NO
--     Use Eigen:                  YES
-- 
--   Interfaces:
--     Python:                     YES
--     Python interpreter:         /usr/bin/python2.6 -B (ver 2.6)
--     Python numpy:               YES
--     Java:                       NO
-- 
--   Documentation:
--     Sphinx:                     NO
--     PdfLaTeX compiler:          /usr/bin/pdflatex
--     Build Documentation:        NO
-- 
--   Tests and samples:
--     Tests:                      YES
--     Examples:                   YES
-- 
--   Install path:                 /usr/local
-- 
--   cvconfig.h is in:             /home/user/Downloads/OpenCV-2.3.1
-- -----------------------------------------------------------------


make

最後にmakeしてインストールをすれば終了

$ make -j2
$ sudo make install
$ sudo ldconfig

インストールが無事に完了は,サンプルのコンパイルで確認することができます.
以下を実行してできた実行ファイルのどれかを動かすことができたらおk
$ cd sample/c/
$ sh build_all.sh


Kinectで遊びたい人は,OpenNIを入れる必要があります.
そのへんのインストールはこっちで