Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

:newcoords+:rotateを繰り返し使うとずれていく #448

Closed
Kanazawanaoaki opened this issue Oct 6, 2020 · 6 comments
Closed

:newcoords+:rotateを繰り返し使うとずれていく #448

Kanazawanaoaki opened this issue Oct 6, 2020 · 6 comments

Comments

@Kanazawanaoaki
Copy link

:newcoordsをした後に:rotateをする関数を繰り返し使うと、どんどん座標がずれていってしまいます。

https://gist.github.com/Kanazawanaoaki/2ae3645f4d9f2f391bb1f9d560ab912e#file-arrow-bag-test-l
のようにnewcoordsをした後にそれぞれ45度、90度回転させる関数(set1)(set2)を定義すると
同じ関数繰り返すとずれていき、

1.irteusgl$ set1
;; (make-irtviewer) executed
now coords #<coordinates #X559139f31e78  500.0 2000.0 1100.0 / 1.571 0.0 0.785> 
please run (set1) again or (set2) 
nil
2.irteusgl$ set1
now coords #<coordinates #X559139f5ef78  500.0 2000.0 1100.0 / 1.571 0.0 1.571> 
please run (set1) again or (set2) 
nil

2つの関数を連続して使うと一回ずつならばうまく行きます。

1.irteusgl$ set1
;; (make-irtviewer) executed
now coords #<coordinates #X55d021123e78  500.0 2000.0 1100.0 / 1.571 0.0 0.785> 
please run (set1) again or (set2) 
nil
2.irteusgl$ set2
now coords #<coordinates #X55d0211476b0  500.0 2000.0 1100.0 / 1.571 0.0 1.571> 
nil

2つの関数を繰り返し使うとそれぞれでずれていきます。

1.irteusgl$ set1
;; (make-irtviewer) executed
now coords #<coordinates #X5582bb968e78  500.0 2000.0 1100.0 / 1.571 0.0 0.785> 
please run (set1) again or (set2) 
nil
2.irteusgl$ set2
now coords #<coordinates #X5582bb98c6b0  500.0 2000.0 1100.0 / 1.571 0.0 1.571> 
nil
3.irteusgl$ set1
now coords #<coordinates #X5582bb602488  500.0 2000.0 1100.0 / 1.571 0.0 1.571> 
please run (set1) again or (set2) 
nil
4.irteusgl$ set2
now coords #<coordinates #X5582bb6128d8  500.0 2000.0 1100.0 / 1.571 0.0 3.142> 
nil
5.irteusgl$ set1
now coords #<coordinates #X5582bb61d028  500.0 2000.0 1100.0 / 1.571 0.0 2.356> 
please run (set1) again or (set2) 
nil
6.irteusgl$ set2
now coords #<coordinates #X5582bb616fb0  500.0 2000.0 1100.0 / 1.571 0.0 -1.571> 
nil
7.irteusgl$ set1
now coords #<coordinates #X5582bb6216e8  500.0 2000.0 1100.0 / 1.571 0.0 3.142> 
please run (set1) again or (set2) 
nil
8.irteusgl$ set2
now coords #<coordinates #X5582bb62e220  500.0 2000.0 1100.0 / 1.571 0.0 -3.798e-15> 
nil

解決策としては、回転させる角度が決まっている場合は事前に:rotateをした後の座標を:newcoordsに渡せば良いのかなと思いますが、何が問題で何が起きているのでしょうか?

@Kanazawanaoaki
Copy link
Author

:rotateをした後の座標を:newcoordsに渡すようにしたところ、ずれていくバグは起こりませんでした。
https://gist.github.com/Kanazawanaoaki/2ae3645f4d9f2f391bb1f9d560ab912e#file-arrow-bag-no-rotate-l

1.irteusgl$ set1
;; (make-irtviewer) executed
now coords #<coordinates #X5625f628c1a0  500.0 2000.0 1100.0 / 1.571 0.0 0.785> 
please run (set1) again or (set2) 
nil
2.irteusgl$ set1
now coords #<coordinates #X5625f62a8928  500.0 2000.0 1100.0 / 1.571 0.0 0.785> 
please run (set1) again or (set2) 
nil
3.irteusgl$ set2
now coords #<coordinates #X5625f5f17148  500.0 2000.0 1100.0 / 1.571 0.0 1.571> 
nil
4.irteusgl$ set2
now coords #<coordinates #X5625f5f26950  500.0 2000.0 1100.0 / 1.571 0.0 1.571> 
nil
5.irteusgl$ set1
now coords #<coordinates #X5625f5f1e9a0  500.0 2000.0 1100.0 / 1.571 0.0 0.785> 
please run (set1) again or (set2) 
nil
6.irteusgl$ set2
now coords #<coordinates #X5625f5f2ba78  500.0 2000.0 1100.0 / 1.571 0.0 1.571> 
nil

@YoheiKakiuchi
Copy link
Member

YoheiKakiuchi commented Oct 6, 2020

jmanual.pdfの p.128 座標系を変更するメソッドに書いてありますが、
:newcoords は代入(コピー)ではなくて、coords(Rot, pos)のインスタンスが同一になります。
https://github.com/euslisp/EusLisp/blob/master/doc/jlatex/jmanual.pdf

それと、#2f((...)) はリードマクロなので、以下の問題と同じで、
set1,set2内のrotationのインスタンスが同一になってしまっているのだろうと想像します。
euslisp/jskeus#583

そういう観点でデバッグしてみてください。
(sys::address obj) すると実際のアドレスが分かります。

@Kanazawanaoaki
Copy link
Author

Kanazawanaoaki commented Oct 6, 2020

@YoheiKakiuchi なるほどありがとうございます。
(sys::address obj)でアドレスを見てみると確かに:newcoodsでセットされているrotが(set1)と(set2)で毎回同じアドレスになっていました。同じ関数を呼ぶたびにその関数で定義されているrotのインスタンスが回転されてしまっていたみたいですね。
https://gist.github.com/Kanazawanaoaki/2ae3645f4d9f2f391bb1f9d560ab912e#file-arrow-bag-address-l

1.irteusgl$ set1
;; (make-irtviewer) executed
worldcoords: #<coordinates #X5631a732a7c0  500.0 2000.0 1100.0 / 1.571 0.0 0.785> arrow address: 94771245135112 rot address: 94771257786864 
nil
2.irteusgl$ set1
worldcoords: #<coordinates #X5631a7346d08  500.0 2000.0 1100.0 / 1.571 0.0 1.571> arrow address: 94771245135112 rot address: 94771257786864 
nil
3.irteusgl$ set2
worldcoords: #<coordinates #X5631a6fb2d68  500.0 2000.0 1100.0 / 1.571 0.0 1.571> arrow address: 94771245135112 rot address: 94771257786552 
nil
4.irteusgl$ set2
worldcoords: #<coordinates #X5631a6fc4130  500.0 2000.0 1100.0 / 1.571 0.0 3.142> arrow address: 94771245135112 rot address: 94771257786552 
nil

そもそも関数内でリードマクロを使うと、その関数を呼び出すたびに同じインスタンスが呼び出されるみたいなので、今回の問題はその時に値が定義されている値にならずにどんどんズレてしまうのが問題なのでしょうか。

(format t "~% out of func ~%")
(setq *hoge*  #2f((0.0 -1.0 0.0) (1.0 0.0 0.0) (0.0 0.0 1.0)))
(print (sys::address *hoge*))
(setq *hoge*  #2f((0.0 -1.0 0.0) (1.0 0.0 0.0) (0.0 0.0 1.0)))
(print (sys::address *hoge*))


(defun hoge ()
  (setq *hoge*  #2f((0.0 -1.0 0.0) (1.0 0.0 0.0) (0.0 0.0 1.0)))
  (print (sys::address *hoge*))
  )

(format t "~% from inside of func ~%")
(hoge)
(hoge)

https://gist.github.com/Kanazawanaoaki/2ae3645f4d9f2f391bb1f9d560ab912e#file-address-test-l

 out of func 
94687871314200
94687872225976

 from inside of func 
94687871649832
94687871649832

@Kanazawanaoaki
Copy link
Author

根本的な解決には無いっていないのかもしれませんが、:newcoordsの引数を渡す時に:copy-worldcoordsを入れて無理やりコピーしてしまってrotのインスタンスが:rotateされるのを防ぐことはできました。

  (send *arrow* :newcoords (send (make-coords :pos (float-vector 500.0 2000.0 1100) :rot #2f((0.0 -1.0 0.0) (1.0 0.0 0.0) (0.0 0.0 1.0))) :copy-worldcoords))
1.irteusgl$ set1
;; (make-irtviewer) executed
worldcoords: #<coordinates #X5584fe2ea160  500.0 2000.0 1100.0 / 1.571 0.0 0.785> arrow address: 94029675230520 rot address: 94029687799680 
nil
2.irteusgl$ set1
worldcoords: #<coordinates #X5584fe305aa8  500.0 2000.0 1100.0 / 1.571 0.0 0.785> arrow address: 94029675230520 rot address: 94029684846664 
nil
3.irteusgl$ set2
worldcoords: #<coordinates #X5584fdf72870  500.0 2000.0 1100.0 / 1.571 0.0 1.571> arrow address: 94029675230520 rot address: 94029684847984 
nil
4.irteusgl$ set2
worldcoords: #<coordinates #X5584fdf823a8  500.0 2000.0 1100.0 / 1.571 0.0 1.571> arrow address: 94029675230520 rot address: 94029687655064 
nil

これが解決策なのかなと思います。

@knorth55
Copy link
Contributor

knorth55 commented Oct 6, 2020

ちなみにですが,こういった金沢君のように新しいcoordinateに物体を移動したい場合は,どうやるのがいいのでしょうか?
お勧めはどれなんでしょうか?

@YoheiKakiuchi
Copy link
Member

YoheiKakiuchi commented Oct 6, 2020

第一に気を付けることには、defunの中にリードマクロを入れないようにするがあります。

coordinatesクラスを作る時は、
(make-coords :pos (float-vector x y z) :rpy (float-vector yaw pitch roll))
がいいように思います。

:rotでの行列指定の場合は、(matrix (float-vector 1 0 0) (float-vector 0 1 0) (float-vector 0 0 1))を使うのだと思いますが、右手系の回転行列以外も与えられるので気をつける必要があります。

また、jmanual.pdfの p.128 座標系を変更するメソッドを書いた経緯としては、
https://github.com/euslisp/EusLisp/blob/master/doc/jlatex/jmanual.pdf

値が直接使われるものを知っておきたいという意図もありました。
値が直接使われるメソッドは要注意で、プライベートにできたらしたいくらいのメソッドかと思います。
なので、極力:newcoordsは使わずに、:transformを使うのが良いのではないかと考えます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants