2024年
12月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

setup diary

2007|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|06|08|11|
2015|01|02|03|04|05|06|07|08|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|

2023-11-20 gsでodf

_ pdfの分割や結合

これまで,pdfを分割したり,結合したりする必要があるときには,imagemagickを使ったり,img2pdfやpdfuniteを使ったりしてきた.一旦画像に変換するかしないかなどの違いはあるが,これらを使う場合には,以下のようにする.

convert *.jpg out.pdf
img2pdf -o out.pdf *.jpg
pdfunite *.pdf output.pdf

gsを使って,似たようなことができるということなので,やってみた.まず,pdfから一部を取り出すには,次のようにする.

gs -dNOPAUSE -dQUIET -dBATCH -sOutputFile=out.pdf -dFirstPage=1 -dLastPage=200 -sDEVICE=pdfwrite in.pdf

次に,pdfを結合するには,以下のようにする.

gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite 
-sOutputFile=out.pdf in1.pdf in2.pdf in3.pdf
pdfのまま処理するので,ファイルサイズはあまり変わらないかとも思ったら,いろいろとやっていたら二倍ぐらいのサイズになってしまった.サイズが変わらない変換方法があれば良いのに.

2023-10-23 pictureとtikz

_ texで図を作る方法

texでpicture環境を使うと,いろいろな図を描くことができる.それでは手が届かないこともできる環境としてtikzというものがあるようなので,使ってみた.両方が使えるように,最初に次のように宣言する.
\documentclass[a4j,dvipdfmx]{jarticle}
\usepackage{color}
\usepackage{epic,eepic}
\usepackage{tikz}
まず,picture環境では,以下のように単位を指定してから,putコマンドで,座標と配置するものを定義すると,図が描ける.
\unitlength 5mm
\begin{picture}(10,10)
\put(5,5){\circle{10}}
\put(5,5){\makebox(0,0){$O$}}
\put(0,0){\color{red} \blacken\path(0,0)(2,2)(2,0)(0,0)}
\put(7,5){\color{cyan} \circle*{2}}
\put(7,6){\color{magenta} \shade\circle{2}}
\end{picture}
一方,tikzでは,tikzpicture環境を使い,デフォルトでは10mm単位なので,必要に応じてscaleを変更して,コマンド,座標,配置するものと指定して,最後にセミコロンをつけて,図を描く.
\begin{tikzpicture}[scale=0.5]
\draw (5,5) circle [radius=5];
\draw (5,5) node {$O$};
\filldraw[red] (0,0)--(2,2)--(2,0)--cycle;
\shade[left color=yellow, right color=cyan] (7,5) circle [radius=1];
\filldraw[draw=magenta,fill=magenta,fill opacity=0.5] (7,6) circle [radius=1];
\end{tikzpicture}
ここで示した例は,そのほんの一部であるが,グラデーションで色を塗ったり,半透明にしたりと,picture環境ではできないことが,tikzではできる.

2023-09-27 最大値の求め方

_ ファイル毎の表示

それぞれのファイルに書かれている数値の最大値をファイル毎に表示したくて,やり方を考えてみた.awkを使ってやろうとしたけど,絶対値や最大値を求めるのが面倒で,ファイル毎の処理も大変だったので,結局rubyを使ってやってしまった.例えば,こんな感じで一行にした.

ruby -e "puts Dir.entries('.').grep(/harm/).sort.map{|fn|open(fn){|f|f.readlines}[1..-1].map{|l|l.split[3].to_f.abs}.max}"

ファイルの処理を書くのは,rubyでは長くなってしまうし,列を取り出す処理も少し面倒なので,別の言語の方が良いかも知れないけど.


2023-08-27 htmlのtable

_ 横や縦のつなげ方

texで表を作っていて,左右とつなげたいときには,

\multicolumn{2}{c}{contents}

などとすれば良いが,上下をつなげたいときは,multirowというパッケージを使わないといけないようだ.一方,htmlだと簡単に上下左右をつなげることができる.左右と上下をつなげるには,それぞれ以下のようにする.

<td colspan=2>
<td rowspan=2>

これを使って,光速(299792458m/s)の語呂合わせを考える表を作ってみた.

2 肉球,憎く,磁極,布告,復刻 肉,服,不休,普及
9
9 食うな,困難,救難,急な 苦無く
7 無く,泣く,急く 泣くに,石窟
9 工夫,国,苦痛,苦に,給餌,給付,クジ
2 強いツヤ,によいつえー 不死,不信,ニシン,自信
4 死後は よ,し
5 御飯,小屋,碁盤,合板,ゴーヤ,ファイヤー
8

これらの語句をつなぎ合わせると,いろいろなものができるが,その中でましなのは,これかな.

299792458()

他の定数もこのような表を作って考えてみようかな.


2023-07-30 maximaでTaylor展開

_ 係数の計算

Taylor展開の係数を計算するのが面倒だったので,maximaを使ってやってみた. どの変数について何次まで展開するかを指定すると,計算してくれる. 具体的な例はこんな感じ.

f(x,r):=1/sqrt(1-2*x*r+r^2);
taylor(f(x,r),r,0,3);

公式をつかって,微分と比較するなら,このようにして確かめられる.

diff(f(x,r),r,3)/3!;

2023-06-29 古い装置とのシリアル通信

_ DTRが制御できない

PCと装置とのインターフェースは,時代とともに徐々に変わって来ているが,長く使われているものとして,RS232Cがある.その通信方法にはいろいろな流儀があるので,特定の装置と通信するのが意外に難しい場合がある.

昔のwindowsからRS232Cを介して制御していた古い装置があるのだが,linux上のwineから動かして使っていた.しかし,wineのversionによっては動かなかったり,クセのある装置である.以前のPCは2017年6月にセットアップしたようだが,そのときも苦労していたようだ.そのシステムもずいぶん古くなってしまったので,別のPCに新しくlinuxを入れて,それから制御しようとしたが,うまくいかない.

今回はオシロを使って,どのような信号が流れているのかを調べてみた.制御できるPCでは,通信の最初にDTR線の電圧がパルス的に変化していたが,うまくいかないPCでは,DTRは最初だけステップ関数的に変化して,二度目以降は動いていないことが分かった.調べてみると,linux kernelは,DTR/DSRフロー制御をサポートしていないという記述を見つけた.この装置を最新のlinux上のwineから動かすのは難しいのかも知れない.


2023-05-29 maximaで三角関数の整理

_ 黄金比

maximaで%pi/5を含む三角関数をいじっていて,少し苦労したので,メモをしておく.表示を一行でできるようにdisplay2d:false;とした後で, exp(%i*%pi/3);とすると,(sqrt(3)*%i)/2+1/2という答えが出てくる. ところが,exp(%i*%pi/5);では%e^((%i*%pi)/5)と,ほぼそのままの結果しか得られない.そこで,

trigrat(exp(%i*%pi/5)+exp(-%i*%pi/5));

とすると,

%i*(sin((2*%pi)/5)-sin((3*%pi)/5))-cos((3*%pi)/5)+cos((2*%pi)/5)+1

と,三角関数で表してはくれるが,複雑な式になる.少なくとも素直に2*cos(%pi/5)として欲しいのに,なかなかそうなってくれない. これを改善するためには,load(ntrig);と,パッケージを入れる必要がある. すると,(sqrt(5)+1)/2と,その値を計算してくれて,黄金比が出てくる. maximaで三角関数などを思ったように変形するのは,意外に難しい.


2023-04-12 ビデオキャプチャをweb配信

_ PCA-DAV2をdebianで

装置についたカメラをwebから監視したいと思っていたのだが,linuxからビデオキャプチャできる良いものが無かったので,なかなか実現できなかったが,ようやくできるようにすることができた.使ったのはPCA-DAV2というUSBビデオキャプチャで,入手が困難だったが売っているところを見つけてなんとか買うことができた.それをdebian bullseyeからmotionを使ってwebに流すまでの設定についてメモをしておきたい.

まず,そのままだと認識されないので,/etc/modprobe.d/em28xx.confの中にoptions em28xx card=29と記述して,再起動すると認識するようになる.カード番号については,13,40,68という情報もあったが,自分の環境では29が正しいようだ.

次に,そのままだとPALが標準設定になっているので,これをNTSCに変更する必要がある.v4l-utilsをインストールして,v4l2-ctl --set-standard=0とすると,NTSCになる.すると,cheeseなどで画像が見れるようになる.

そして,web配信はmotionを使った.これをインストールしたら,/etc/motion/motion.confを変更して必要な設定を行う.daemonをoffにして,NTSCにするためにnormを1にするのが重要で,あとは自分の環境に合わせて設定する.今回はpicture_outputもmovie_outputもoffにして,保存は行わないようにした.root権限でmotionを実行すると,8081ポートから動画が見れるようになる.

最後に,motionが自動で起動するように,まずはchown motion:motion /var/log/motion/motion.logとしてログファイルの権限を変更する.そして,systemctl start motionとすると,自動起動できるようになる.

まだ,装置が実際に動いているときの動作を確認していないので,なんとも言えないが,便利になると良いな.


2023-03-09 rubyの更新

_ 1.8.7から2.7.4へ

10年ぐらい前にセットアップしたPCを更新したら,rubyのversionがかなり違っていて,プログラムを書き換えるのに苦労した.特に,文字コードとしてShift_JISを使っていたので,その部分も面倒だった.正確にはCP932というコードだったので,Shift_JISを指定しても動かなかったが. 主に引っかかった点を,羅列しようと思う.
  • requireのフォルダ指定が必要
  • jcodeが廃止
  • parsedateが廃止されたので,require "date"としてからDate::parse(self).to_timeを使った
  • # coding: cp932を指定した.
  • CGIのformを取り込むために,CGI.accept_charset="cp932"とした
  • ファイルの読み書きで,"w:cp932"などと指定した
大体は以上の変更で動くようになったようだが,今後まだバグが出るかも知れない.

_ 2023/3/30追記

あと,cookieで日本語を使っている場合に,CGI.unescape(ci[0])などとしなければならなかった.


2023-03-01 dataの抽出

_ 古いKaleidaGraphから

かなり古いKaleidaGraphから数値dataを抽出したいという話を聞いたので,そのデータをもらって,構造を解析してみた.それなりに単純な構造をしていたので,データ抽出プログラムをrubyで書いてみた.それがこんな感じ.
qda=ARGV[0]
dat=qda.sub(/\.qda$/i,"_.dat")
d=open(qda,"rb"){|f|f.read}
n=d[0,16].unpack("n*")
c=n[8] # byte size of the last comment
n=n[1] # the number of data
sz=d[0x200,2*n].unpack("n*") # size of each data
tp=d[0x200+2*n,2*n].unpack("n*") # type
names=d[0x200+4*n,40*n].unpack("a40"*n).map(&:strip)
r=d[(0x200+4*n+40*n)..-1]
sz=sz.zip(tp).map{|s,t|
  a,b="g","" # big endian float
  a,b="N","Z21" if t==1 # string
  a,b="G","" if t==2 # big endian 64bit float
  *data,r=r.unpack(a*s+"n"*s+b*s+"a*")
  msk=data[s,s] # mask
  str=data[2*s,s] # string
  data=data[0,s] # numeric
  if t==2 # date or time
    td=r[0,8].unpack("C*")[3]
    data=data.map{|l|(Time.gm(l>3e9?1904:2000)+l).getutc.strftime("%d-%m-%Y")} if td==0 #date
    data=data.map{|l|Time.at(l).getutc.strftime("%H:%M:%S")} if td==1 #12:34:56
    data=data.map{|l|["%02d"]*2*":"%l.divmod(60)} if td==2 #12:34
  end
  r=r[136..-1]
  data=str if t==1
  data
}
mx=sz.map(&:size).max
sz=sz.map{|l|l.fill(0,l.size...mx)}.transpose
open(dat,"w"){|f|
  f.puts "# "+r.gsub(/\x0d\x0a?/,"\n# ") if r.size>0
  f.puts names*", "
  sz.each{|l|f.puts l*", "}
}
まず,引数として与えたファイルを読み込むが,2バイト目からdataの数を,14バイト目からがコメントのサイズを表すようなので,それを取り込む.200hバイトから,それぞれのdataの長さがあり,その次に型だと思われるdataがある.その後に,40バイトずつのdataの名前があり,そのあとにdata本体とマスクだと思われるdataと文字列の場合には21バイドずつの文字列があり,その後にはdataの名前と良くわからないdataが合計136バイトあるようだ.ちなみに,それぞれはbig endianである.さらに,日付の表記は日月年の順番で,内部では秒単位の倍精度浮動小数点で表されているようである.時刻も同様である.ただ,文字列のdataの場合に,data本体には何が保存されているかはよく調べなかった.まあ,特定のversionのKaleidaGraphでセーブしたdataしか変換できないかも知れないが,今回の目的は達成したので,良しとしよう.