Open Kanazawanaoaki opened 2 years ago
As far as I know the closest thing we have to a yaml utility in euslisp is the rosparam interface.
You could try to couple set/get param with (unix:system "rosparam load/dump ...")
calls, or write a simple encoder /decoder and maybe add it to the euslib or roseus-utils.
Here is a start:
(defun alistp (alist)
(and (listp alist) (every #'consp alist)))
(defun format-alist (lst output-stream &optional (lvl 0))
(dolist (l lst)
(let ((name (car l))
(val (cdr l)))
(spaces (* 2 lvl) output-stream)
(format output-stream "~a: " name)
(if (alistp val)
(progn
(terpri output-stream)
(format-alist val output-stream (1+ lvl)))
(if (listp val)
(dolist (v val)
(terpri output-stream)
(spaces (* 2 (1+ lvl)) output-stream)
(format output-stream "- ~A" v))
(print val output-stream))))))
(defun dump-param (name output-stream)
(format-alist (acons name (ros::get-param name) nil) output-stream))
;; (dump-param "myparam" t)
Thank you very much.
I confirmed that I can load and dump yaml with known format from euslisp (to be exact, roseus?) that I wanted to do.
I feel that simple encoder/decoder can be implemented relatively easily if we use rosparam, so I'll think about it for a moment.
input.yaml
val1: 100
val2: 200
from-yaml.l
#!/usr/bin/env roseus
(ros::roseus "test")
(setq *val1* nil)
(setq *val2* nil)
(defun yaml-load (input-file)
(unix:system (format nil "rosparam load ~A yaml_load_eus" input-file))
(setq *val1* (ros::get-param "/yaml_load_eus/val1"))
(setq *val2* (ros::get-param "/yaml_load_eus/val2"))
(format t "~%load params from ~A ~%" input-file)
(format t " now val1 is ~A ~%" *val1*)
(format t " now val2 is ~A ~%" *val2*)
)
(defun yaml-dump (output-file)
(unix:system "rosparam delete /yaml_dump_eus")
(ros::set-param "/yaml_dump_eus/val1" *val1*)
(ros::set-param "/yaml_dump_eus/val2" *val2*)
(unix:system (format nil "rosparam dump ~A yaml_dump_eus" output-file))
(format t "~%dump params to ~A ~%" output-file)
)
(yaml-load "input.yaml")
(yaml-dump "output.yaml")
in command line
$ ls
from-yaml.l input.yaml
$ roseus from-yaml.l
load params from input.yaml
now val1 is 100.0
now val2 is 200.0
ERROR: parameter [/yaml_dump_eus] is not set
dump params to output.yaml
$ cat output.yaml
val1: 100.0
val2: 200.0
Using https://github.com/jsk-ros-pkg/jsk_roseus/pull/710 , I created a program to read and write any yaml file in roseus by using the load and dump functions of rosparam. https://gist.github.com/Kanazawanaoaki/b9aba2c4bb1a51e138057574beab7dfe
(defun yaml-load (input-file)
(unix:system "rosparam delete /eus_yaml_load")
(unix:system (format nil "rosparam load ~A eus_yaml_load" input-file))
(setq *params* (ros::get-param "/eus_yaml_load"))
(unix:system "rosparam delete /eus_yaml_load")
(format t "~%load params from ~A~%" input-file)
(format t " now param is ~A ~%" *params*)
)
(defun yaml-dump (output-file)
(unix:system "rosparam delete /eus_yaml_dump")
(ros::set-param "/eus_yaml_dump" *params*)
(unix:system (format nil "rosparam dump ~A eus_yaml_dump" output-file))
(unix:system "rosparam delete /eus_yaml_dump")
(format t "~%dump params to ~A~%" output-file)
)
Is there a good way and need to add such functions to jsk_roseus?
Glad that you were able to read/ write yaml files as expected.
However, I am afraid that this still may be a little too 'hacky' to add to jsk_roseus...
That's right ... I don't think it's something that can be added to jsk_roseus either. Is it better to leave it as a sample program in this issue? I have no idea how to add it to jsk_roseus as a feature.
I think it is ok to leave it as a sample program in this issue.
Euslispでyaml形式のファイルを読み書きするための関数や読み書きしている例はありますでしょうか?
pythonやcommon lispの例はあるみたいなのでそれらを参考にして作るか,使いたいyamlファイルの形式などがある程度決まっている場合は自分でparserを作るというのも有り得そうです.
また,読み込むだけならrosparamとして渡すという作戦が有効そうかなと思っています.
因みにjsonの例はjsk_roseus/roseus_mongo/euslisp/json/にあるようです.