From de7a887e5187376bd87d5d1a8aafedb7a2a833d4 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 25 Jul 2022 18:41:57 +0900
Subject: [PATCH 01/77] [jsk_unitree_startup/cross] Add python3-venv for catkin
 virtualenv

---
 jsk_unitree_robot/cross/docker/deb-packages.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/jsk_unitree_robot/cross/docker/deb-packages.txt b/jsk_unitree_robot/cross/docker/deb-packages.txt
index 84684bfd7c..f4b65059c9 100644
--- a/jsk_unitree_robot/cross/docker/deb-packages.txt
+++ b/jsk_unitree_robot/cross/docker/deb-packages.txt
@@ -1125,6 +1125,7 @@ python3-setuptools
 python3-simplejson
 python3-six
 python3-urllib3
+python3-venv
 python3-webencodings
 python3-wheel
 python3-xdg

From f9d4baccc8d87973a118e2a3497225e644b89898 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 11:41:25 +0900
Subject: [PATCH 02/77] [jsk_unitree_startup/cross] Use sitecustomize.py
 instead of setting PYTHONPATH

---
 jsk_unitree_robot/cross/build_ros1.sh         |  2 ++
 jsk_unitree_robot/cross/build_user.sh         |  4 ++-
 .../ros1_dependencies_setup.bash              |  6 +++--
 .../cross/startup_scripts/sitecustomize.py    | 26 +++++++++++++++++++
 4 files changed, 35 insertions(+), 3 deletions(-)
 create mode 100644 jsk_unitree_robot/cross/startup_scripts/sitecustomize.py

diff --git a/jsk_unitree_robot/cross/build_ros1.sh b/jsk_unitree_robot/cross/build_ros1.sh
index 05712d2b1d..008db39f2a 100755
--- a/jsk_unitree_robot/cross/build_ros1.sh
+++ b/jsk_unitree_robot/cross/build_ros1.sh
@@ -50,6 +50,7 @@ docker run -it --rm \
   -e INSTALL_ROOT=${INSTALL_ROOT} \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies:ro \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies_setup.bash:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies_setup.bash:ro \
+  -v ${PWD}/startup_scripts/sitecustomize.py:/usr/lib/python2.7/sitecustomize.py:ro \
   -v ${HOST_INSTALL_ROOT}/ros1_inst:/opt/jsk/${INSTALL_ROOT}/ros1_inst:rw \
   -v ${PWD}/${SOURCE_ROOT}:/home/user/${SOURCE_ROOT}:rw \
   ros1-unitree:${TARGET_MACHINE} \
@@ -69,3 +70,4 @@ docker run -it --rm \
     " 2>&1 | tee ${TARGET_MACHINE}_build_ros1.log
 
 cp ${PWD}/startup_scripts/system_setup.bash ${HOST_INSTALL_ROOT}/
+cp ${PWD}/startup_scripts/sitecustomize.py ${HOST_INSTALL_ROOT}/
diff --git a/jsk_unitree_robot/cross/build_user.sh b/jsk_unitree_robot/cross/build_user.sh
index f18831c411..d0855e30a1 100755
--- a/jsk_unitree_robot/cross/build_user.sh
+++ b/jsk_unitree_robot/cross/build_user.sh
@@ -50,6 +50,8 @@ docker run -it --rm \
   -v ${HOST_INSTALL_ROOT}/ros1_inst:/opt/jsk/${INSTALL_ROOT}/ros1_inst:ro \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies_setup.bash:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies_setup.bash:ro \
   -v ${HOST_INSTALL_ROOT}/system_setup.bash:/opt/jsk/${INSTALL_ROOT}/system_setup.bash:ro \
+  -v ${HOST_INSTALL_ROOT}/sitecustomize.py:/usr/lib/python2.7/sitecustomize.py:ro \
+  -v ${HOST_INSTALL_ROOT}/sitecustomize.py:/usr/lib/python3.6/sitecustomize.py:ro \
   -v ${PWD}/${SOURCE_ROOT}:/opt/jsk/User:rw \
   -v ${PWD}/rosinstall_generator_unreleased.py:/home/user/rosinstall_generator_unreleased.py:ro \
   ros1-unitree:${TARGET_MACHINE} \
@@ -59,7 +61,7 @@ docker run -it --rm \
     set -xeuf -o pipefail && \
     cd /opt/jsk/User && \
     [ ${UPDATE_SOURCE_ROOT} -eq 0 ] || ROS_PACKAGE_PATH=src:\${ROS_PACKAGE_PATH} /home/user/rosinstall_generator_unreleased.py jsk_${TARGET_ROBOT}_startup ${TARGET_ROBOT}eus --rosdistro melodic --exclude RPP --exclude mongodb_store | tee user.repos && \
-    [ ${UPDATE_SOURCE_ROOT} -eq 0 -o -z \"\$(cat user.repos)\" ] || PYTHONPATH= vcs import src < user.repos && \
+    [ ${UPDATE_SOURCE_ROOT} -eq 0 -o -z \"\$(cat user.repos)\" ] || vcs import src < user.repos && \
     catkin build jsk_${TARGET_ROBOT}_startup ${TARGET_ROBOT}eus -s -vi \
         --cmake-args -DCATKIN_ENABLE_TESTING=FALSE \
     " 2>&1 | tee ${TARGET_MACHINE}_build_user.log
diff --git a/jsk_unitree_robot/cross/startup_scripts/ros1_dependencies_setup.bash b/jsk_unitree_robot/cross/startup_scripts/ros1_dependencies_setup.bash
index bb83142ace..2ab07f4d83 100755
--- a/jsk_unitree_robot/cross/startup_scripts/ros1_dependencies_setup.bash
+++ b/jsk_unitree_robot/cross/startup_scripts/ros1_dependencies_setup.bash
@@ -5,14 +5,16 @@
 export CMAKE_PREFIX_PATH="/opt/jsk/System/ros1_dependencies:${CMAKE_PREFIX_PATH}"
 export PKG_CONFIG_PATH="/opt/jsk/System/ros1_dependencies/lib/pkgconfig:${PKG_CONFIG_PATH}"
 export LD_LIBRARY_PATH="/opt/jsk/System/ros1_dependencies/lib:${LD_LIBRARY_PATH}"
-export PYTHONPATH="/opt/jsk/System/ros1_dependencies/lib/python2.7/site-packages:${PYTHONPATH}"
+# Python's sys.path is automatically set in /usr/lib/python2.7/sitecustomize.py
+# export PYTHONPATH="/opt/jsk/System/ros1_dependencies/lib/python2.7/site-packages:${PYTHONPATH}"
 
 # GI : for gir1.2-gstreamer-1.0, which is installed by ros1_dependencies_build_scripts/0006-gstreamer
 export GI_TYPELIB_PATH="/opt/jsk/System/ros1_dependencies/lib/girepository-1.0"
 
 # Python
 export LD_LIBRARY_PATH="/opt/jsk/System/Python/lib:${LD_LIBRARY_PATH}"
-export PYTHONPATH="/opt/jsk/System/Python/lib/python2.7/site-packages:${PYTHONPATH}"
+# Python's sys.path is automatically set in /usr/lib/python2.7/sitecustomize.py
+# export PYTHONPATH="/opt/jsk/System/Python/lib/python2.7/site-packages:${PYTHONPATH}"
 export PATH="/opt/jsk/System/Python/bin:${PATH}"
 
 
diff --git a/jsk_unitree_robot/cross/startup_scripts/sitecustomize.py b/jsk_unitree_robot/cross/startup_scripts/sitecustomize.py
new file mode 100644
index 0000000000..f37cd9bfe9
--- /dev/null
+++ b/jsk_unitree_robot/cross/startup_scripts/sitecustomize.py
@@ -0,0 +1,26 @@
+# install the apport exception handler if available
+import site
+import sys
+import os.path as osp
+
+site.PREFIXES += [
+    '/opt/jsk/System/Python/',
+    '/opt/jsk/System/ros1_dependencies/',
+    '/opt/jsk/System/ros1_inst/',
+]
+
+paths = []
+for path in site.getsitepackages():
+    site_package = osp.join(osp.dirname(path), 'site-packages')
+    if site_package != path and osp.exists(site_package):
+        paths.append(site_package)
+    else:
+        paths.append(path)
+
+sys.path.extend(paths)
+try:
+    import apport_python_hook
+except ImportError:
+    pass
+else:
+    apport_python_hook.install()

From 554a87bb09f05793adc3a0d29fc82159d55cc908 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 16:05:12 +0900
Subject: [PATCH 03/77] [jsk_unitree_startup/cross] Recursively append python
 site/dist-package paths

---
 .../cross/startup_scripts/sitecustomize.py      | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/jsk_unitree_robot/cross/startup_scripts/sitecustomize.py b/jsk_unitree_robot/cross/startup_scripts/sitecustomize.py
index f37cd9bfe9..6e0abdf861 100644
--- a/jsk_unitree_robot/cross/startup_scripts/sitecustomize.py
+++ b/jsk_unitree_robot/cross/startup_scripts/sitecustomize.py
@@ -1,6 +1,7 @@
 # install the apport exception handler if available
 import site
 import sys
+import os
 import os.path as osp
 
 site.PREFIXES += [
@@ -9,13 +10,25 @@
     '/opt/jsk/System/ros1_inst/',
 ]
 
+
+def recursively_listup_paths(path):
+    paths = []
+    for sub_path in os.listdir(path):
+        sub_full_path = osp.join(path, sub_path)
+        if osp.isdir(sub_full_path) and (sub_path.endswith('.egg-info') or sub_path.endswith('.egg')):
+            paths.append(sub_full_path)
+    return paths
+
+
 paths = []
 for path in site.getsitepackages():
+    if osp.exists(path):
+        paths.append(path)
+        paths.extend(recursively_listup_paths(path))
     site_package = osp.join(osp.dirname(path), 'site-packages')
     if site_package != path and osp.exists(site_package):
         paths.append(site_package)
-    else:
-        paths.append(path)
+        paths.extend(recursively_listup_paths(site_package))
 
 sys.path.extend(paths)
 try:

From f52c4de1573329e1ce40c532732c9cf0a522068b Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 16:06:55 +0900
Subject: [PATCH 04/77] [jsk_unitree_startup/cross] Add google_chat_ros

---
 jsk_unitree_robot/cross/repos/unitree.repos       | 8 ++++++++
 jsk_unitree_robot/jsk_unitree_startup/package.xml | 1 +
 2 files changed, 9 insertions(+)

diff --git a/jsk_unitree_robot/cross/repos/unitree.repos b/jsk_unitree_robot/cross/repos/unitree.repos
index 8e8e056cc1..d6a9239589 100644
--- a/jsk_unitree_robot/cross/repos/unitree.repos
+++ b/jsk_unitree_robot/cross/repos/unitree.repos
@@ -21,3 +21,11 @@ repositories:
     type: git
     url: https://github.com/Affonso-Gui/app_manager
     version: enable-parallel-run-apps
+  google_chat_ros:
+    type: git
+    url: https://github.com/mqcmd196/jsk_3rdparty
+    version: google_chat_ros
+  catkin_virtualenv:
+    type: git
+    url: https://github.com/locusrobotics/catkin_virtualenv
+    version: 0.8.0
diff --git a/jsk_unitree_robot/jsk_unitree_startup/package.xml b/jsk_unitree_robot/jsk_unitree_startup/package.xml
index 9723686b9a..59e3a350d7 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/package.xml
+++ b/jsk_unitree_robot/jsk_unitree_startup/package.xml
@@ -16,6 +16,7 @@
   <run_depend>rosserial_python</run_depend>
   <run_depend>teleop_twist_joy</run_depend>
   <run_depend>respeaker_ros</run_depend>
+  <run_depend>google_chat_ros</run_depend>
 
   <!-- for diagnostic aggregator -->
   <run_depend>diagnostic_aggregator</run_depend>

From dd38754b9cc4383edd00e13558399d2076b17ce4 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 17:21:28 +0900
Subject: [PATCH 05/77] [jsk_unitree_startup/cross] Use bug-fix version of
 catkin-virtualenv

---
 jsk_unitree_robot/cross/repos/unitree.repos | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/jsk_unitree_robot/cross/repos/unitree.repos b/jsk_unitree_robot/cross/repos/unitree.repos
index d6a9239589..8fa7e17eb0 100644
--- a/jsk_unitree_robot/cross/repos/unitree.repos
+++ b/jsk_unitree_robot/cross/repos/unitree.repos
@@ -27,5 +27,5 @@ repositories:
     version: google_chat_ros
   catkin_virtualenv:
     type: git
-    url: https://github.com/locusrobotics/catkin_virtualenv
-    version: 0.8.0
+    url: https://github.com/iory/catkin_virtualenv
+    version: avoid-catkin_run_tests_target

From c0b2cc82ef3fd1a211f2387593f8ac865a156466 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 17:22:06 +0900
Subject: [PATCH 06/77] [jsk_unitree_startup/cross] Install python3
 dependencies for catkin_virtualenv

---
 jsk_unitree_robot/cross/build_ros1_dependencies.sh         | 5 ++++-
 jsk_unitree_robot/cross/repos/go1_requirements_python3.txt | 2 ++
 2 files changed, 6 insertions(+), 1 deletion(-)
 create mode 100644 jsk_unitree_robot/cross/repos/go1_requirements_python3.txt

diff --git a/jsk_unitree_robot/cross/build_ros1_dependencies.sh b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
index 56b8f6a418..fd718e4b8e 100755
--- a/jsk_unitree_robot/cross/build_ros1_dependencies.sh
+++ b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
@@ -24,6 +24,7 @@ cp repos/ros1_dependencies.repos ${SOURCE_ROOT}/
 
 mkdir -p ${HOST_INSTALL_ROOT}/Python
 cp repos/go1_requirements.txt ${SOURCE_ROOT}/go1_requirements.txt
+cp repos/go1_requirements_python3.txt ${SOURCE_ROOT}/go1_requirements_python3.txt
 
 docker run -it --rm \
   -u $(id -u $USER) \
@@ -40,8 +41,10 @@ docker run -it --rm \
     for script_file in \$(ls /home/user/ros1_dependencies_build_scripts/|sort); do
       /home/user/ros1_dependencies_build_scripts/\$script_file || exit 1;
     done && \
+    pip3 install -U --user pip && \
     pip install -U --user pip && \
     export PYTHONPATH=\"/opt/jsk/System/ros1_dependencies/lib/python2.7/site-packages\" && \
     export PKG_CONFIG_PATH=\"/opt/jsk/${INSTALL_ROOT}/ros1_dependencies/lib/pkgconfig\" && \
-    ~/.local/bin/pip install --prefix=/opt/jsk/${INSTALL_ROOT}/Python -r /home/user/ros1_dependencies_sources/go1_requirements.txt \
+    ~/.local/bin/pip install --prefix=/opt/jsk/${INSTALL_ROOT}/Python -r /home/user/ros1_dependencies_sources/go1_requirements.txt && \
+    PYTHONPATH= ~/.local/bin/pip3 install --prefix=/opt/jsk/${INSTALL_ROOT}/Python -r /home/user/ros1_dependencies_sources/go1_requirements_python3.txt \
     " 2>&1 | tee ${TARGET_MACHINE}_build_ros1_dependencies.log
diff --git a/jsk_unitree_robot/cross/repos/go1_requirements_python3.txt b/jsk_unitree_robot/cross/repos/go1_requirements_python3.txt
new file mode 100644
index 0000000000..3f9f5d0b12
--- /dev/null
+++ b/jsk_unitree_robot/cross/repos/go1_requirements_python3.txt
@@ -0,0 +1,2 @@
+# needeed by catkin_virtualenv
+catkin-pkg

From 533783844bf0e0f97328a20920123e583e447abf Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 17:55:06 +0900
Subject: [PATCH 07/77] [jsk_unitree_startup/cross] Add
 JSK_UNITREE_COMPILE_PARALLEL option to change number of parallel jobs

---
 jsk_unitree_robot/cross/build_ros1_dependencies.sh              | 1 +
 .../cross/ros1_dependencies_build_scripts/1001-urdfdom-headers  | 2 +-
 .../cross/ros1_dependencies_build_scripts/1002-urdfdom          | 2 +-
 .../cross/ros1_dependencies_build_scripts/1003-assimp           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1004-colladadom       | 2 +-
 .../cross/ros1_dependencies_build_scripts/1005-yaml-cpp         | 2 +-
 .../cross/ros1_dependencies_build_scripts/1007-snappy           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1008-opencv           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1009-python-sip       | 2 +-
 .../cross/ros1_dependencies_build_scripts/1024-liblcm           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1025-alsa-lib         | 2 +-
 .../cross/ros1_dependencies_build_scripts/1026-db5              | 1 +
 .../cross/ros1_dependencies_build_scripts/1028-libportaudio2    | 2 +-
 .../cross/ros1_dependencies_build_scripts/1030-flac             | 2 +-
 .../cross/ros1_dependencies_build_scripts/1031-libncurses       | 2 +-
 .../cross/ros1_dependencies_build_scripts/1032-speech-tools     | 1 +
 .../cross/ros1_dependencies_build_scripts/1033-festival         | 1 +
 17 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/jsk_unitree_robot/cross/build_ros1_dependencies.sh b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
index fd718e4b8e..3fb19f5e01 100755
--- a/jsk_unitree_robot/cross/build_ros1_dependencies.sh
+++ b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
@@ -29,6 +29,7 @@ cp repos/go1_requirements_python3.txt ${SOURCE_ROOT}/go1_requirements_python3.tx
 docker run -it --rm \
   -u $(id -u $USER) \
   -e INSTALL_ROOT=${INSTALL_ROOT} \
+  -e JSK_UNITREE_COMPILE_PARALLEL=${JSK_UNITREE_COMPILE_PARALLEL} \
   -v ${PWD}/ros1_dependencies_build_scripts:/home/user/ros1_dependencies_build_scripts:ro \
   -v ${PWD}/${SOURCE_ROOT}:/home/user/ros1_dependencies_sources:rw \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk//${INSTALL_ROOT}/ros1_dependencies:rw \
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers
index f9e2b9e3e0..21a2f3f06b 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers
@@ -10,4 +10,4 @@ cmake \
   -DCMAKE_BUILD_TYPE=Release \
   ../../src/urdfdom-headers/urdfdom_headers-1.0.0
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom
index e4b8ea0d15..3357529dec 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom
@@ -10,4 +10,4 @@ cmake \
   -DCMAKE_BUILD_TYPE=Release \
   ../../src/urdfdom/urdfdom-1.0.0
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp
index 3dc23b4619..a33874a214 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp
@@ -23,4 +23,4 @@ cmake \
   -DASSIMP_ENABLE_BOOST_WORKAROUND=OFF \
   ${SOURCE_DIR}
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom
index a74c303a62..d00d1d4feb 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom
@@ -27,4 +27,4 @@ cmake \
   -DOPT_DOUBLE_PRECISION=ON \
   ${SOURCE_DIR}
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp
index 0f1bcd80a0..509ed0bec3 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp
@@ -19,4 +19,4 @@ cmake \
   -DYAML_CPP_BUILD_TOOLS=ON \
   ${SOURCE_DIR}
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy
index a2a46b22b8..9644678b08 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy
@@ -18,4 +18,4 @@ cmake \
   -DBUILD_SHARED_LIBS=on \
   ${SOURCE_DIR}
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv
index 4f52260bf5..7bd2ce8cab 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv
@@ -50,4 +50,4 @@ cmake \
   -DOPENCV_CONFIG_INSTALL_PATH=lib/cmake/OpenCV \
   ${SOURCE_DIR}
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip
index 5920f9e9e1..7b8d2e6dfd 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip
@@ -18,4 +18,4 @@ python \
     -e /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/include \
     -b /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/bin \
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm
index 54bb3e40bc..ae2ef2f7d6 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm
@@ -20,4 +20,4 @@ automake --add-missing
 autoconf
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib
index 0b548baf83..4e9fbe46b5 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib
@@ -16,4 +16,4 @@ cd ${SOURCE_DIR}
 
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1026-db5 b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1026-db5
index f82fb4fa88..eb39e405da 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1026-db5
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1026-db5
@@ -16,4 +16,5 @@ cd ${SOURCE_DIR}/build_unix
 
 ../dist/configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies --build $(uname -m)-unknown-linux-gnu --enable-cxx --enable-compat185
 
+# Can be compiled safely with j1.
 make -j1 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2 b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2
index d13d19e6cd..4b6db9066c 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2
@@ -20,4 +20,4 @@ cmake \
   -DCMAKE_BUILD_TYPE=Release \
   ${SOURCE_DIR}
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac
index 0455aab6ba..186f2c2193 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac
@@ -18,4 +18,4 @@ automake --add-missing
 autoconf
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses
index 7638ed7532..08242b8135 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses
@@ -14,4 +14,4 @@ cd ${SOURCE_DIR}
 
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies -with-shared
 
-make -j4 install
+make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1032-speech-tools b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1032-speech-tools
index c2447e8fd6..62a5b3a116 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1032-speech-tools
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1032-speech-tools
@@ -30,6 +30,7 @@ export PROJECT_MAJOR_VERSION=2
 
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
+# Can be compiled safely with j1.
 make -j1 PULSEAUDIO=none
 
 cp lib/*.a    /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/lib
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1033-festival b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1033-festival
index 8060ba8551..4873594a46 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1033-festival
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1033-festival
@@ -28,6 +28,7 @@ libtoolize
 autoconf
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
+# Can be compiled safely with j1.
 EST="../speech_tools" make -j1 all
 
 cp src/main/festival src/main/festival_client bin/text2wave /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/bin/

From 785af9ec1688e502b442af478565d22d2b65646f Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 21:58:06 +0900
Subject: [PATCH 08/77] [jsk_unitree_startup/cross] Install sitecustomize.py
 for real unitree robot

---
 jsk_unitree_robot/cross/install.sh | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index e05fa2f36f..e7d4a60fb4 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -64,6 +64,12 @@ function copy_data () {
     ssh-keygen -f "${HOME}/.ssh/known_hosts" -R "${hostname}" || echo "OK"
     sshpass -p $PASS ssh -o StrictHostKeyChecking=no ${user}@${hostname} exit
 
+    if [[ "${TARGET_DIRECTORY}" == "System" ]]; then
+        sshpass -p 123 scp ${TARGET_MACHINE}_${TARGET_DIRECTORY}/sitecustomize.py ${user}@${hostname}:/tmp/sitecustomize.py
+        sshpass -p $PASS ssh -t ${user}@${hostname} "sudo cp -f /tmp/sitecustomize.py /usr/lib/python2.7/sitecustomize.py"
+        sshpass -p $PASS ssh -t ${user}@${hostname} "sudo cp -f /tmp/sitecustomize.py /usr/lib/python3/sitecustomize.py"
+    fi
+
     # cehck disk space
     echo "Copy ${TARGET_MACHINE}_${TARGET_DIRECTORY} ...."
     echo "==="

From 1e045b1082fa203156c71d594135b72c51882b4f Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 23:40:04 +0900
Subject: [PATCH 09/77] [jsk_unitree_startup] Fixed install.sh command
 description. -d is correct instead of -D

---
 jsk_unitree_robot/cross/README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/README.md b/jsk_unitree_robot/cross/README.md
index 4c38e5c985..451e5766ff 100644
--- a/jsk_unitree_robot/cross/README.md
+++ b/jsk_unitree_robot/cross/README.md
@@ -29,7 +29,7 @@ Caution!!! It will take more than a few hours !! So for JSK users, download the
 
 Run following command to copy ROS1 base sytem to Go1 onboard computer. This should be done only in the first time. So normally user do not have to run this command
 ```
-./install.sh -p 123 -D System
+./install.sh -p 123 -d System
 ```
 
 ### Build `jsk_unitree_robot` software on Docker

From bba78e2cae3a3b72dc8ed9442093c4dab6c47c52 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 23:40:53 +0900
Subject: [PATCH 10/77] [jsk_unitree_startup] Use perl instead of 'grep -Po'

---
 jsk_unitree_robot/cross/install.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index e7d4a60fb4..d5db4cd71c 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -54,7 +54,7 @@ function copy_data () {
     fi
 
     # Check if robot is reachable
-    reachability=$(ping -c4 ${hostname} 2>/dev/null | awk '/---/,0' | grep -Po '[0-9]{1,3}(?=% packet loss)')
+    reachability=$(ping -c4 ${hostname} 2>/dev/null | awk '/---/,0' | perl -nle'print $& while m{[0-9]{1,3}(?=% packet loss)}g')
     if [ -z "$reachability" ] || [ "$reachability" == 100 ]; then
         echo "ERROR: ${hostname} unreachable" 1>&2
         exit 2

From b1c13cd31488dac88cc544742dd1350e2f76b115 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 23:43:45 +0900
Subject: [PATCH 11/77] [jsk_unitree_startup/cross] Install LTE settings only
 TARGET_DIRECTORY is User case

---
 jsk_unitree_robot/cross/install.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index d5db4cd71c..c06fba1a87 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -113,12 +113,12 @@ function copy_data () {
         sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find respeaker_ros)/config/60-respeaker.rules /etc/udev/rules.d/60-respeaker.rules"
         #
         sshpass -p $PASS ssh -t ${user}@${hostname} "ls -al /etc/udev/rules.d/; sudo systemctl restart udev"
-    fi
 
-    # enable Internet with USB LTE module
-    if [[ "${hostname}" == "192.168.123.161" ]]; then
-        sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find jsk_unitree_startup)/config/dhcpcd.conf /etc/dhcpcd.conf"
-        sshpass -p $PASS ssh -t ${user}@${hostname} "sudo systemctl restart dhcpcd"
+        # enable Internet with USB LTE module
+        if [[ "${hostname}" == "192.168.123.161" ]]; then
+            sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find jsk_unitree_startup)/config/dhcpcd.conf /etc/dhcpcd.conf"
+            sshpass -p $PASS ssh -t ${user}@${hostname} "sudo systemctl restart dhcpcd"
+        fi
     fi
     set +x
 }

From f55266b60ca34e17a8764a5cb0a6a2dd9ebe0293 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Tue, 26 Jul 2022 23:44:29 +0900
Subject: [PATCH 12/77] [jsk_unitree_startup/cross] Use sshpass instead of
 /usr/bin/sshpass

---
 jsk_unitree_robot/cross/install.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index c06fba1a87..6b8d5df4bd 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -98,9 +98,9 @@ function copy_data () {
     sshpass -p $PASS ssh -t ${user}@${hostname} "test -e /opt/jsk" || \
         sshpass -p $PASS ssh -t ${user}@${hostname} "sudo mkdir -p /opt/jsk && sudo chown -R \$(id -u \${USER}):\$(id -g \${USER}) /opt/jsk && ls -al /opt/jsk"
 
-    rsync --rsh="/usr/bin/sshpass -p $PASS ssh -o StrictHostKeyChecking=no -l ${user}" -avz --delete --delete-excluded --exclude "*.pyc" --exclude "^logs/" ${TARGET_MACHINE}_${TARGET_DIRECTORY}/ ${hostname}:/opt/jsk/${TARGET_DIRECTORY}
+    rsync --rsh="sshpass -p $PASS ssh -o StrictHostKeyChecking=no -l ${user}" -avz --delete --delete-excluded --exclude "*.pyc" --exclude "^logs/" ${TARGET_MACHINE}_${TARGET_DIRECTORY}/ ${hostname}:/opt/jsk/${TARGET_DIRECTORY}
     if [[ "${TARGET_DIRECTORY}" == "User" ]]; then
-        rsync --rsh="/usr/bin/sshpass -p $PASS ssh -o StrictHostKeyChecking=no -l ${user}" -avz --delete --delete-excluded ../jsk_unitree_startup/autostart/ ${hostname}:Unitree/autostart/jsk_startup
+        rsync --rsh="sshpass -p $PASS ssh -o StrictHostKeyChecking=no -l ${user}" -avz --delete --delete-excluded ../jsk_unitree_startup/autostart/ ${hostname}:Unitree/autostart/jsk_startup
         # https://stackoverflow.com/questions/23395363/make-patch-return-0-when-skipping-an-already-applied-patch
 
         # On Air, we need to start unitree_bringup at 129.168.123.13

From 1c21dd2f0da85e39e2c6096321c1b70be081614a Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Wed, 27 Jul 2022 00:51:57 +0900
Subject: [PATCH 13/77] [jsk_unitree_startup/cross] Use bug-fix branch for
 enabling aarch64 (diaglogflow)

---
 jsk_unitree_robot/cross/repos/unitree.repos | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/repos/unitree.repos b/jsk_unitree_robot/cross/repos/unitree.repos
index 8fa7e17eb0..b5c40d7b01 100644
--- a/jsk_unitree_robot/cross/repos/unitree.repos
+++ b/jsk_unitree_robot/cross/repos/unitree.repos
@@ -23,7 +23,7 @@ repositories:
     version: enable-parallel-run-apps
   google_chat_ros:
     type: git
-    url: https://github.com/mqcmd196/jsk_3rdparty
+    url: https://github.com/iory/jsk_3rdparty
     version: google_chat_ros
   catkin_virtualenv:
     type: git

From c60b7d97a9077498bf54068c99e01ac6b1779531 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Wed, 27 Jul 2022 02:05:37 +0900
Subject: [PATCH 14/77] [jsk_unitree_startup/cross] Set default value 4 to
 JSK_UNITREE_COMPILE_PARALLEL

---
 jsk_unitree_robot/cross/build_ros1_dependencies.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/jsk_unitree_robot/cross/build_ros1_dependencies.sh b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
index 3fb19f5e01..e36626291c 100755
--- a/jsk_unitree_robot/cross/build_ros1_dependencies.sh
+++ b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
@@ -4,6 +4,7 @@ TARGET_MACHINE="${TARGET_MACHINE:-arm64v8}"
 HOST_INSTALL_ROOT="${BASE_ROOT:-${PWD}}/"${TARGET_MACHINE}_System
 INSTALL_ROOT=System
 SOURCE_ROOT=${TARGET_MACHINE}_ws_ros1_dependencies_sources
+JSK_UNITREE_COMPILE_PARALLEL="${JSK_UNITREE_COMPILE_PARALLEL:-4}"
 
 if [ -e "${SOURCE_ROOT}" ]; then
     echo "WARNING: Source directory is found ${SOURCE_ROOT}" 1>&2

From ce8e63a1ea34f9c214833470d794723ed9792d78 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Wed, 27 Jul 2022 14:48:53 +0900
Subject: [PATCH 15/77] Revert "[jsk_unitree_startup/cross] Add
 JSK_UNITREE_COMPILE_PARALLEL option to change number of parallel jobs"

This reverts commit 7f9dd4a2a7a8eab21791dd8f1a7e662a088a515d.
---
 jsk_unitree_robot/cross/build_ros1_dependencies.sh              | 1 -
 .../cross/ros1_dependencies_build_scripts/1001-urdfdom-headers  | 2 +-
 .../cross/ros1_dependencies_build_scripts/1002-urdfdom          | 2 +-
 .../cross/ros1_dependencies_build_scripts/1003-assimp           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1004-colladadom       | 2 +-
 .../cross/ros1_dependencies_build_scripts/1005-yaml-cpp         | 2 +-
 .../cross/ros1_dependencies_build_scripts/1007-snappy           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1008-opencv           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1009-python-sip       | 2 +-
 .../cross/ros1_dependencies_build_scripts/1024-liblcm           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1025-alsa-lib         | 2 +-
 .../cross/ros1_dependencies_build_scripts/1026-db5              | 1 -
 .../cross/ros1_dependencies_build_scripts/1028-libportaudio2    | 2 +-
 .../cross/ros1_dependencies_build_scripts/1030-flac             | 2 +-
 .../cross/ros1_dependencies_build_scripts/1031-libncurses       | 2 +-
 .../cross/ros1_dependencies_build_scripts/1032-speech-tools     | 1 -
 .../cross/ros1_dependencies_build_scripts/1033-festival         | 1 -
 17 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/jsk_unitree_robot/cross/build_ros1_dependencies.sh b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
index e36626291c..e1fcc8b020 100755
--- a/jsk_unitree_robot/cross/build_ros1_dependencies.sh
+++ b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
@@ -30,7 +30,6 @@ cp repos/go1_requirements_python3.txt ${SOURCE_ROOT}/go1_requirements_python3.tx
 docker run -it --rm \
   -u $(id -u $USER) \
   -e INSTALL_ROOT=${INSTALL_ROOT} \
-  -e JSK_UNITREE_COMPILE_PARALLEL=${JSK_UNITREE_COMPILE_PARALLEL} \
   -v ${PWD}/ros1_dependencies_build_scripts:/home/user/ros1_dependencies_build_scripts:ro \
   -v ${PWD}/${SOURCE_ROOT}:/home/user/ros1_dependencies_sources:rw \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk//${INSTALL_ROOT}/ros1_dependencies:rw \
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers
index 21a2f3f06b..f9e2b9e3e0 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers
@@ -10,4 +10,4 @@ cmake \
   -DCMAKE_BUILD_TYPE=Release \
   ../../src/urdfdom-headers/urdfdom_headers-1.0.0
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom
index 3357529dec..e4b8ea0d15 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom
@@ -10,4 +10,4 @@ cmake \
   -DCMAKE_BUILD_TYPE=Release \
   ../../src/urdfdom/urdfdom-1.0.0
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp
index a33874a214..3dc23b4619 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp
@@ -23,4 +23,4 @@ cmake \
   -DASSIMP_ENABLE_BOOST_WORKAROUND=OFF \
   ${SOURCE_DIR}
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom
index d00d1d4feb..a74c303a62 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom
@@ -27,4 +27,4 @@ cmake \
   -DOPT_DOUBLE_PRECISION=ON \
   ${SOURCE_DIR}
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp
index 509ed0bec3..0f1bcd80a0 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp
@@ -19,4 +19,4 @@ cmake \
   -DYAML_CPP_BUILD_TOOLS=ON \
   ${SOURCE_DIR}
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy
index 9644678b08..a2a46b22b8 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy
@@ -18,4 +18,4 @@ cmake \
   -DBUILD_SHARED_LIBS=on \
   ${SOURCE_DIR}
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv
index 7bd2ce8cab..4f52260bf5 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv
@@ -50,4 +50,4 @@ cmake \
   -DOPENCV_CONFIG_INSTALL_PATH=lib/cmake/OpenCV \
   ${SOURCE_DIR}
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip
index 7b8d2e6dfd..5920f9e9e1 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip
@@ -18,4 +18,4 @@ python \
     -e /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/include \
     -b /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/bin \
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm
index ae2ef2f7d6..54bb3e40bc 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm
@@ -20,4 +20,4 @@ automake --add-missing
 autoconf
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib
index 4e9fbe46b5..0b548baf83 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib
@@ -16,4 +16,4 @@ cd ${SOURCE_DIR}
 
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1026-db5 b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1026-db5
index eb39e405da..f82fb4fa88 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1026-db5
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1026-db5
@@ -16,5 +16,4 @@ cd ${SOURCE_DIR}/build_unix
 
 ../dist/configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies --build $(uname -m)-unknown-linux-gnu --enable-cxx --enable-compat185
 
-# Can be compiled safely with j1.
 make -j1 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2 b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2
index 4b6db9066c..d13d19e6cd 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2
@@ -20,4 +20,4 @@ cmake \
   -DCMAKE_BUILD_TYPE=Release \
   ${SOURCE_DIR}
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac
index 186f2c2193..0455aab6ba 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac
@@ -18,4 +18,4 @@ automake --add-missing
 autoconf
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses
index 08242b8135..7638ed7532 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses
@@ -14,4 +14,4 @@ cd ${SOURCE_DIR}
 
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies -with-shared
 
-make -j${JSK_UNITREE_COMPILE_PARALLEL:-4} install
+make -j4 install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1032-speech-tools b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1032-speech-tools
index 62a5b3a116..c2447e8fd6 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1032-speech-tools
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1032-speech-tools
@@ -30,7 +30,6 @@ export PROJECT_MAJOR_VERSION=2
 
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-# Can be compiled safely with j1.
 make -j1 PULSEAUDIO=none
 
 cp lib/*.a    /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/lib
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1033-festival b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1033-festival
index 4873594a46..8060ba8551 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1033-festival
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1033-festival
@@ -28,7 +28,6 @@ libtoolize
 autoconf
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-# Can be compiled safely with j1.
 EST="../speech_tools" make -j1 all
 
 cp src/main/festival src/main/festival_client bin/text2wave /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/bin/

From 5cf2dec70a38d291a8987f94a2a134f8f6e86920 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Wed, 27 Jul 2022 14:49:09 +0900
Subject: [PATCH 16/77] Revert "[jsk_unitree_startup/cross] Set default value 4
 to JSK_UNITREE_COMPILE_PARALLEL"

This reverts commit ff8c07358cd87281b5926f04fb74facb06591f38.
---
 jsk_unitree_robot/cross/build_ros1_dependencies.sh | 1 -
 1 file changed, 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/build_ros1_dependencies.sh b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
index e1fcc8b020..fd718e4b8e 100755
--- a/jsk_unitree_robot/cross/build_ros1_dependencies.sh
+++ b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
@@ -4,7 +4,6 @@ TARGET_MACHINE="${TARGET_MACHINE:-arm64v8}"
 HOST_INSTALL_ROOT="${BASE_ROOT:-${PWD}}/"${TARGET_MACHINE}_System
 INSTALL_ROOT=System
 SOURCE_ROOT=${TARGET_MACHINE}_ws_ros1_dependencies_sources
-JSK_UNITREE_COMPILE_PARALLEL="${JSK_UNITREE_COMPILE_PARALLEL:-4}"
 
 if [ -e "${SOURCE_ROOT}" ]; then
     echo "WARNING: Source directory is found ${SOURCE_ROOT}" 1>&2

From 6023c3614baab4b7080b06339884ba8febe66f62 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Wed, 27 Jul 2022 14:54:41 +0900
Subject: [PATCH 17/77] [jsk_unitree_startup/cross] Passthrough MAKEFLAGS

---
 jsk_unitree_robot/cross/build_ros1.sh                           | 2 ++
 jsk_unitree_robot/cross/build_ros1_dependencies.sh              | 2 ++
 .../cross/ros1_dependencies_build_scripts/1001-urdfdom-headers  | 2 +-
 .../cross/ros1_dependencies_build_scripts/1002-urdfdom          | 2 +-
 .../cross/ros1_dependencies_build_scripts/1003-assimp           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1004-colladadom       | 2 +-
 .../cross/ros1_dependencies_build_scripts/1005-yaml-cpp         | 2 +-
 .../cross/ros1_dependencies_build_scripts/1007-snappy           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1008-opencv           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1009-python-sip       | 2 +-
 .../cross/ros1_dependencies_build_scripts/1024-liblcm           | 2 +-
 .../cross/ros1_dependencies_build_scripts/1025-alsa-lib         | 2 +-
 .../1027-jack-audio-connection-kit                              | 2 +-
 .../cross/ros1_dependencies_build_scripts/1028-libportaudio2    | 2 +-
 .../cross/ros1_dependencies_build_scripts/1030-flac             | 2 +-
 .../cross/ros1_dependencies_build_scripts/1031-libncurses       | 2 +-
 16 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/jsk_unitree_robot/cross/build_ros1.sh b/jsk_unitree_robot/cross/build_ros1.sh
index 008db39f2a..2a5ef09574 100755
--- a/jsk_unitree_robot/cross/build_ros1.sh
+++ b/jsk_unitree_robot/cross/build_ros1.sh
@@ -4,6 +4,7 @@ TARGET_MACHINE="${TARGET_MACHINE:-arm64v8}"
 HOST_INSTALL_ROOT="${BASE_ROOT:-${PWD}}/"${TARGET_MACHINE}_System
 INSTALL_ROOT=System
 SOURCE_ROOT=${TARGET_MACHINE}_ws_system
+MAKEFLAGS=${MAKEFLAGS:-'-j4'}
 
 UPDATE_SOURCE_ROOT=1  # TRUE
 if [ -e "${SOURCE_ROOT}" ]; then
@@ -48,6 +49,7 @@ PR2EUS="pr2eus"
 docker run -it --rm \
   -u $(id -u $USER) \
   -e INSTALL_ROOT=${INSTALL_ROOT} \
+  -e MAKEFLAGS=${MAKEFLAGS} \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies:ro \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies_setup.bash:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies_setup.bash:ro \
   -v ${PWD}/startup_scripts/sitecustomize.py:/usr/lib/python2.7/sitecustomize.py:ro \
diff --git a/jsk_unitree_robot/cross/build_ros1_dependencies.sh b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
index fd718e4b8e..e194ad4155 100755
--- a/jsk_unitree_robot/cross/build_ros1_dependencies.sh
+++ b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
@@ -4,6 +4,7 @@ TARGET_MACHINE="${TARGET_MACHINE:-arm64v8}"
 HOST_INSTALL_ROOT="${BASE_ROOT:-${PWD}}/"${TARGET_MACHINE}_System
 INSTALL_ROOT=System
 SOURCE_ROOT=${TARGET_MACHINE}_ws_ros1_dependencies_sources
+MAKEFLAGS=${MAKEFLAGS:-'-j4'}
 
 if [ -e "${SOURCE_ROOT}" ]; then
     echo "WARNING: Source directory is found ${SOURCE_ROOT}" 1>&2
@@ -29,6 +30,7 @@ cp repos/go1_requirements_python3.txt ${SOURCE_ROOT}/go1_requirements_python3.tx
 docker run -it --rm \
   -u $(id -u $USER) \
   -e INSTALL_ROOT=${INSTALL_ROOT} \
+  -e MAKEFLAGS=${MAKEFLAGS} \
   -v ${PWD}/ros1_dependencies_build_scripts:/home/user/ros1_dependencies_build_scripts:ro \
   -v ${PWD}/${SOURCE_ROOT}:/home/user/ros1_dependencies_sources:rw \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk//${INSTALL_ROOT}/ros1_dependencies:rw \
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers
index f9e2b9e3e0..5c43882e1c 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1001-urdfdom-headers
@@ -10,4 +10,4 @@ cmake \
   -DCMAKE_BUILD_TYPE=Release \
   ../../src/urdfdom-headers/urdfdom_headers-1.0.0
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom
index e4b8ea0d15..30144b316e 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1002-urdfdom
@@ -10,4 +10,4 @@ cmake \
   -DCMAKE_BUILD_TYPE=Release \
   ../../src/urdfdom/urdfdom-1.0.0
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp
index 3dc23b4619..acd3d11160 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1003-assimp
@@ -23,4 +23,4 @@ cmake \
   -DASSIMP_ENABLE_BOOST_WORKAROUND=OFF \
   ${SOURCE_DIR}
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom
index a74c303a62..152fb4da51 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1004-colladadom
@@ -27,4 +27,4 @@ cmake \
   -DOPT_DOUBLE_PRECISION=ON \
   ${SOURCE_DIR}
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp
index 0f1bcd80a0..1fc3ddf698 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1005-yaml-cpp
@@ -19,4 +19,4 @@ cmake \
   -DYAML_CPP_BUILD_TOOLS=ON \
   ${SOURCE_DIR}
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy
index a2a46b22b8..fb065a0a23 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1007-snappy
@@ -18,4 +18,4 @@ cmake \
   -DBUILD_SHARED_LIBS=on \
   ${SOURCE_DIR}
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv
index 4f52260bf5..adccf09285 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1008-opencv
@@ -50,4 +50,4 @@ cmake \
   -DOPENCV_CONFIG_INSTALL_PATH=lib/cmake/OpenCV \
   ${SOURCE_DIR}
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip
index 5920f9e9e1..dbeb077680 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1009-python-sip
@@ -18,4 +18,4 @@ python \
     -e /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/include \
     -b /opt/jsk/${INSTALL_ROOT}/ros1_dependencies/bin \
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm
index 54bb3e40bc..20022e923b 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1024-liblcm
@@ -20,4 +20,4 @@ automake --add-missing
 autoconf
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib
index 0b548baf83..32bc8248f3 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1025-alsa-lib
@@ -16,4 +16,4 @@ cd ${SOURCE_DIR}
 
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1027-jack-audio-connection-kit b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1027-jack-audio-connection-kit
index a39053b965..57e32c0585 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1027-jack-audio-connection-kit
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1027-jack-audio-connection-kit
@@ -17,4 +17,4 @@ cd ${SOURCE_DIR}
 ./autogen.sh
 CFLAGS="-I/opt/jsk/${INSTALL_ROOT}/ros1_dependencies/include" LIBS="-L/opt/jsk/${INSTALL_ROOT}/ros1_dependencies/lib" ./configure --enable-force-install --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2 b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2
index d13d19e6cd..9c6c607838 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1028-libportaudio2
@@ -20,4 +20,4 @@ cmake \
   -DCMAKE_BUILD_TYPE=Release \
   ${SOURCE_DIR}
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac
index 0455aab6ba..5de19e6a74 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1030-flac
@@ -18,4 +18,4 @@ automake --add-missing
 autoconf
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
-make -j4 install
+make install
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses
index 7638ed7532..bdcab81e05 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1031-libncurses
@@ -14,4 +14,4 @@ cd ${SOURCE_DIR}
 
 ./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies -with-shared
 
-make -j4 install
+make install

From b9bbd112a2624234696b043271c390f5bdd9448f Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Wed, 27 Jul 2022 16:36:04 +0900
Subject: [PATCH 18/77] [jsk_unitree_startup/cross] Add comments for
 unitree.repos

---
 jsk_unitree_robot/cross/repos/unitree.repos | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/jsk_unitree_robot/cross/repos/unitree.repos b/jsk_unitree_robot/cross/repos/unitree.repos
index b5c40d7b01..2bbcd8887a 100644
--- a/jsk_unitree_robot/cross/repos/unitree.repos
+++ b/jsk_unitree_robot/cross/repos/unitree.repos
@@ -21,11 +21,20 @@ repositories:
     type: git
     url: https://github.com/Affonso-Gui/app_manager
     version: enable-parallel-run-apps
+    # For parallel feature of app manager
+    # https://github.com/PR2/app_manager/pull/59
   google_chat_ros:
     type: git
     url: https://github.com/iory/jsk_3rdparty
     version: google_chat_ros
+    # Support Google Chat API.
+    # https://github.com/jsk-ros-pkg/jsk_3rdparty/pull/323
+    # To support aarch64, used the following branch. https://github.com/mqcmd196/jsk_3rdparty/pull/2
   catkin_virtualenv:
     type: git
     url: https://github.com/iory/catkin_virtualenv
     version: avoid-catkin_run_tests_target
+    # At current, if we do a catkin build with CATKIN_ENABLE_TESTING=FALSE,
+    # we get the error 'Unknown CMake command "catkin_run_tests_target"'
+    # when calling catkin_generate_virtualenv. The following PR fixes this error.
+    # https://github.com/locusrobotics/catkin_virtualenv/pull/89

From e753fba8daa52de2e4334f0aa6d68ce29f03c729 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Thu, 28 Jul 2022 23:15:39 +0900
Subject: [PATCH 19/77] [jsk_unitree_startup/cross] Passthrough python
 libraries on run_user.sh

---
 jsk_unitree_robot/cross/run_user.sh | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/jsk_unitree_robot/cross/run_user.sh b/jsk_unitree_robot/cross/run_user.sh
index 07c9f39652..b0b2bf57b5 100755
--- a/jsk_unitree_robot/cross/run_user.sh
+++ b/jsk_unitree_robot/cross/run_user.sh
@@ -17,6 +17,8 @@ docker run -it --rm \
   -v ${HOST_INSTALL_ROOT}/ros1_inst:/opt/jsk/${INSTALL_ROOT}/ros1_inst:ro \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies_setup.bash:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies_setup.bash:ro \
   -v ${HOST_INSTALL_ROOT}/system_setup.bash:/opt/jsk/${INSTALL_ROOT}/system_setup.bash:ro \
+  -v ${HOST_INSTALL_ROOT}/sitecustomize.py:/usr/lib/python2.7/sitecustomize.py:ro \
+  -v ${HOST_INSTALL_ROOT}/sitecustomize.py:/usr/lib/python3.6/sitecustomize.py:ro \
   -v ${PWD}/${SOURCE_ROOT}:/opt/jsk/User:rw \
   ros1-unitree:${TARGET_MACHINE} \
   bash -c "echo 'source /opt/jsk/User/user_setup.bash; env; cd /opt/jsk/User' > ~/.bashrc; exec \"\$0\""

From ff338cf35b7f762d99e0d2c27fea8e0ce62f2071 Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Fri, 29 Jul 2022 00:08:15 +0900
Subject: [PATCH 20/77] [unitree/cross] Add prerequisite command to readme

---
 jsk_unitree_robot/cross/README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/jsk_unitree_robot/cross/README.md b/jsk_unitree_robot/cross/README.md
index 451e5766ff..a15b6f05c4 100644
--- a/jsk_unitree_robot/cross/README.md
+++ b/jsk_unitree_robot/cross/README.md
@@ -14,9 +14,9 @@ $ sudo usermod -aG docker $USER
 $ newgrp
 ```
 
-2. Install Qemu software
+2. Install Qemu software and other prerequisites
 ```
-$ sudo apt install -y qemu-user-static
+$ sudo apt install -y qemu-user-static sshpass python-vcstool
 ```
 
 ### Build ROS System on Docker  (Run only the fist time per host computer)

From 33cf239cd1f835dbffb6963ab0425bc362f46700 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Fri, 29 Jul 2022 14:04:06 +0900
Subject: [PATCH 21/77] [jsk_unitree_startup/cross] Modified google_chat_ros
 branch

---
 jsk_unitree_robot/cross/repos/unitree.repos | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/jsk_unitree_robot/cross/repos/unitree.repos b/jsk_unitree_robot/cross/repos/unitree.repos
index 2bbcd8887a..8acfa235f2 100644
--- a/jsk_unitree_robot/cross/repos/unitree.repos
+++ b/jsk_unitree_robot/cross/repos/unitree.repos
@@ -25,11 +25,10 @@ repositories:
     # https://github.com/PR2/app_manager/pull/59
   google_chat_ros:
     type: git
-    url: https://github.com/iory/jsk_3rdparty
+    url: https://github.com/mqcmd196/jsk_3rdparty
     version: google_chat_ros
     # Support Google Chat API.
     # https://github.com/jsk-ros-pkg/jsk_3rdparty/pull/323
-    # To support aarch64, used the following branch. https://github.com/mqcmd196/jsk_3rdparty/pull/2
   catkin_virtualenv:
     type: git
     url: https://github.com/iory/catkin_virtualenv

From 3e1247f9949066dff3a0fff33210a613b2eafe00 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Fri, 29 Jul 2022 14:06:06 +0900
Subject: [PATCH 22/77] [jsk_unitree_startup/cross] Add comment for
 reachability

---
 jsk_unitree_robot/cross/install.sh | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index 6b8d5df4bd..fdebc5868c 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -54,6 +54,8 @@ function copy_data () {
     fi
 
     # Check if robot is reachable
+    # Use perl instead of `grep -Po '[0-9]{1,3}(?=% packet loss)'` for Mac environment.
+    # See https://stackoverflow.com/questions/16658333/grep-p-no-longer-works-how-can-i-rewrite-my-searches/16658690#16658690
     reachability=$(ping -c4 ${hostname} 2>/dev/null | awk '/---/,0' | perl -nle'print $& while m{[0-9]{1,3}(?=% packet loss)}g')
     if [ -z "$reachability" ] || [ "$reachability" == 100 ]; then
         echo "ERROR: ${hostname} unreachable" 1>&2

From d6c223f77cac452d842393951fc904078ab73d13 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Fri, 29 Jul 2022 14:17:07 +0900
Subject: [PATCH 23/77] Revert "[jsk_unitree_startup/cross] Add python3-venv
 for catkin virtualenv"

This reverts commit d62d039b2a72497bd4c7126159a959f093c6796e.
---
 jsk_unitree_robot/cross/docker/deb-packages.txt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/docker/deb-packages.txt b/jsk_unitree_robot/cross/docker/deb-packages.txt
index f4b65059c9..84684bfd7c 100644
--- a/jsk_unitree_robot/cross/docker/deb-packages.txt
+++ b/jsk_unitree_robot/cross/docker/deb-packages.txt
@@ -1125,7 +1125,6 @@ python3-setuptools
 python3-simplejson
 python3-six
 python3-urllib3
-python3-venv
 python3-webencodings
 python3-wheel
 python3-xdg

From 4b5dd183c8de170c3f278d27749903e825316935 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Fri, 29 Jul 2022 14:18:49 +0900
Subject: [PATCH 24/77] [jsk_unitree_startup/cross] Enable virtualenv via pip
 install

---
 jsk_unitree_robot/cross/repos/go1_requirements_python3.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/jsk_unitree_robot/cross/repos/go1_requirements_python3.txt b/jsk_unitree_robot/cross/repos/go1_requirements_python3.txt
index 3f9f5d0b12..4e9c52a6c8 100644
--- a/jsk_unitree_robot/cross/repos/go1_requirements_python3.txt
+++ b/jsk_unitree_robot/cross/repos/go1_requirements_python3.txt
@@ -1,2 +1,5 @@
 # needeed by catkin_virtualenv
+backports_abc
 catkin-pkg
+singledispatch
+virtualenv

From 706a5b21f8fb41c4d8bac0b42bf73e9fec5905e3 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Fri, 29 Jul 2022 17:02:21 +0900
Subject: [PATCH 25/77] [jsk_unitree_startup/cross] Use unitree branch at
 catkin_virtualenv

---
 jsk_unitree_robot/cross/repos/unitree.repos | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/repos/unitree.repos b/jsk_unitree_robot/cross/repos/unitree.repos
index 8acfa235f2..5d4d73ae19 100644
--- a/jsk_unitree_robot/cross/repos/unitree.repos
+++ b/jsk_unitree_robot/cross/repos/unitree.repos
@@ -32,8 +32,13 @@ repositories:
   catkin_virtualenv:
     type: git
     url: https://github.com/iory/catkin_virtualenv
-    version: avoid-catkin_run_tests_target
+    version: unitree
     # At current, if we do a catkin build with CATKIN_ENABLE_TESTING=FALSE,
     # we get the error 'Unknown CMake command "catkin_run_tests_target"'
     # when calling catkin_generate_virtualenv. The following PR fixes this error.
     # https://github.com/locusrobotics/catkin_virtualenv/pull/89
+    #
+    # Some python environments may not have ensurepip installed.
+    # Also, some users may not be able to use sudo apt install to install python3-venv (sudo command), etc.
+    # The following PR will enable catkin_virtualenv in environments without ensurepip by doing get-pip.py within venv.
+    # https://github.com/locusrobotics/catkin_virtualenv/pull/90

From e578bb82daef8b8de0bb023f18f8e6ca1ac8ce99 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sat, 30 Jul 2022 17:08:30 +0900
Subject: [PATCH 26/77] [jsk_unitree_startup/cross] Install sysctl.conf to
 passthrough packet

---
 jsk_unitree_robot/cross/install.sh            |  1 +
 .../jsk_unitree_startup/config/sysctl.conf    | 69 +++++++++++++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/config/sysctl.conf

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index fdebc5868c..d99d078d5c 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -119,6 +119,7 @@ function copy_data () {
         # enable Internet with USB LTE module
         if [[ "${hostname}" == "192.168.123.161" ]]; then
             sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find jsk_unitree_startup)/config/dhcpcd.conf /etc/dhcpcd.conf"
+            sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find jsk_unitree_startup)/config/sysctl.conf /etc/sysctl.conf"
             sshpass -p $PASS ssh -t ${user}@${hostname} "sudo systemctl restart dhcpcd"
         fi
     fi
diff --git a/jsk_unitree_robot/jsk_unitree_startup/config/sysctl.conf b/jsk_unitree_robot/jsk_unitree_startup/config/sysctl.conf
new file mode 100644
index 0000000000..43006774dc
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/config/sysctl.conf
@@ -0,0 +1,69 @@
+#
+# /etc/sysctl.conf - Configuration file for setting system variables
+# See /etc/sysctl.d/ for additional system variables.
+# See sysctl.conf (5) for information.
+#
+
+#kernel.domainname = example.com
+
+# Uncomment the following to stop low-level messages on console
+#kernel.printk = 3 4 1 3
+
+##############################################################3
+# Functions previously found in netbase
+#
+
+# Uncomment the next two lines to enable Spoof protection (reverse-path filter)
+# Turn on Source Address Verification in all interfaces to
+# prevent some spoofing attacks
+#net.ipv4.conf.default.rp_filter=1
+#net.ipv4.conf.all.rp_filter=1
+
+# Uncomment the next line to enable TCP/IP SYN cookies
+# See http://lwn.net/Articles/277146/
+# Note: This may impact IPv6 TCP sessions too
+#net.ipv4.tcp_syncookies=1
+
+# Uncomment the next line to enable packet forwarding for IPv4
+# Required to transfer packat to jetson.
+net.ipv4.ip_forward=1
+
+# Uncomment the next line to enable packet forwarding for IPv6
+#  Enabling this option disables Stateless Address Autoconfiguration
+#  based on Router Advertisements for this host
+#net.ipv6.conf.all.forwarding=1
+
+
+###################################################################
+# Additional settings - these settings can improve the network
+# security of the host and prevent against some network attacks
+# including spoofing attacks and man in the middle attacks through
+# redirection. Some network environments, however, require that these
+# settings are disabled so review and enable them as needed.
+#
+# Do not accept ICMP redirects (prevent MITM attacks)
+#net.ipv4.conf.all.accept_redirects = 0
+#net.ipv6.conf.all.accept_redirects = 0
+# _or_
+# Accept ICMP redirects only for gateways listed in our default
+# gateway list (enabled by default)
+# net.ipv4.conf.all.secure_redirects = 1
+#
+# Do not send ICMP redirects (we are not a router)
+#net.ipv4.conf.all.send_redirects = 0
+#
+# Do not accept IP source route packets (we are not a router)
+#net.ipv4.conf.all.accept_source_route = 0
+#net.ipv6.conf.all.accept_source_route = 0
+#
+# Log Martian Packets
+#net.ipv4.conf.all.log_martians = 1
+#
+
+###################################################################
+# Magic system request Key
+# 0=disable, 1=enable all, >1 bitmask of sysrq functions
+# See https://www.kernel.org/doc/html/latest/admin-guide/sysrq.html
+# for what other values do
+#kernel.sysrq=438
+

From 82acc9f0876c265b6a93093ca1bc6abe823159df Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sat, 30 Jul 2022 17:17:10 +0900
Subject: [PATCH 27/77] [jsk_unitree_startup/cross] Install iptables.ipv4.nat
 to passthrough packets via LTE and wlan2

---
 jsk_unitree_robot/cross/install.sh            |  1 +
 .../config/iptables.ipv4.nat                  | 38 +++++++++++++++++++
 2 files changed, 39 insertions(+)
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/config/iptables.ipv4.nat

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index d99d078d5c..4ca599d583 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -120,6 +120,7 @@ function copy_data () {
         if [[ "${hostname}" == "192.168.123.161" ]]; then
             sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find jsk_unitree_startup)/config/dhcpcd.conf /etc/dhcpcd.conf"
             sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find jsk_unitree_startup)/config/sysctl.conf /etc/sysctl.conf"
+            sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find jsk_unitree_startup)/config/iptables.ipv4.nat /etc/iptables.ipv4.nat"
             sshpass -p $PASS ssh -t ${user}@${hostname} "sudo systemctl restart dhcpcd"
         fi
     fi
diff --git a/jsk_unitree_robot/jsk_unitree_startup/config/iptables.ipv4.nat b/jsk_unitree_robot/jsk_unitree_startup/config/iptables.ipv4.nat
new file mode 100644
index 0000000000..fdfa466fda
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/config/iptables.ipv4.nat
@@ -0,0 +1,38 @@
+# Generated by xtables-save v1.8.2 on Tue Apr 26 15:11:12 2022
+*filter
+:INPUT ACCEPT [248560:31230459]
+:FORWARD ACCEPT [107:13046]
+:OUTPUT ACCEPT [979900:329384767]
+-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
+# Passthrough packets via LTE module.
+-A FORWARD -i usb0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A FORWARD -o usb0 -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A FORWARD -i usb0 -o wlan1 -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A FORWARD -i wlan1 -o usb0 -m state --state RELATED,ESTABLISHED -j ACCEPT
+# Passthrough packets via wlan2 (for sparky)
+-A FORWARD -i wlan2 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A FORWARD -o wlan2 -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A FORWARD -i wlan2 -o wlan1 -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A FORWARD -i wlan1 -o wlan2 -m state --state RELATED,ESTABLISHED -j ACCEPT
+COMMIT
+# Completed on Tue Apr 26 15:11:12 2022
+# Generated by xtables-save v1.8.2 on Tue Apr 26 15:11:12 2022
+*nat
+:PREROUTING ACCEPT [276:28555]
+:INPUT ACCEPT [165:13454]
+:POSTROUTING ACCEPT [355:25705]
+:OUTPUT ACCEPT [414:29614]
+-A POSTROUTING -o wlan2 -j MASQUERADE
+-A POSTROUTING -o usb0 -j MASQUERADE
+COMMIT
+# Completed on Tue Apr 26 15:11:12 2022
+# Generated by xtables-save v1.8.2 on Tue Apr 26 15:11:12 2022
+*mangle
+:PREROUTING ACCEPT [1265282:660359078]
+:INPUT ACCEPT [1262670:659548895]
+:FORWARD ACCEPT [2562:800616]
+:OUTPUT ACCEPT [979900:329384767]
+:POSTROUTING ACCEPT [982534:330195437]
+COMMIT
+# Completed on Tue Apr 26 15:11:12 2022

From 1a675157f17e94e408e1e7cbca5d2d7964f3c616 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Wed, 3 Aug 2022 19:51:02 +0900
Subject: [PATCH 28/77] [jsk_unitree_startup/cross] Add OPTIONS to passthrough
 user id for mac compatibility

---
 jsk_unitree_robot/cross/build_ros1.sh             | 15 +++++++++++++--
 .../cross/build_ros1_dependencies.sh              | 12 ++++++++++--
 jsk_unitree_robot/cross/build_user.sh             | 11 ++++++++++-
 jsk_unitree_robot/cross/run_user.sh               | 11 ++++++++++-
 4 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/jsk_unitree_robot/cross/build_ros1.sh b/jsk_unitree_robot/cross/build_ros1.sh
index 2a5ef09574..31548745c5 100755
--- a/jsk_unitree_robot/cross/build_ros1.sh
+++ b/jsk_unitree_robot/cross/build_ros1.sh
@@ -33,7 +33,9 @@ mkdir -p ${HOST_INSTALL_ROOT}/ros1_inst
 if [ ${UPDATE_SOURCE_ROOT} -eq 1 ]; then
     vcs import --force --retry 3 --shallow ${SOURCE_ROOT}/src < repos/roseus_no_window.repos
     for dir in euslisp jskeus; do ls ${SOURCE_ROOT}/src/$dir/patches/; rsync -avz ${SOURCE_ROOT}/src/$dir/patches/ ${SOURCE_ROOT}/src/$dir; done
-    sed -i s@:{version}@0.0.0@ ${SOURCE_ROOT}/src/euslisp/package.xml ${SOURCE_ROOT}/src/jskeus/package.xml
+    # linux can use sed -i'.bak' and latest mac also supports same syntax.
+    # https://stackoverflow.com/questions/4247068/sed-command-with-i-option-failing-on-mac-but-works-on-linux/14813278#14813278
+    sed -i.bak s@:{version}@0.0.0@ ${SOURCE_ROOT}/src/euslisp/package.xml ${SOURCE_ROOT}/src/jskeus/package.xml
 fi
 wget https://patch-diff.githubusercontent.com/raw/PR2/pr2_mechanism/pull/346.diff -O ${SOURCE_ROOT}/pr2_mechanism-346.diff
 
@@ -46,8 +48,17 @@ JSK_ROBOT_UTILS="jsk_network_tools"
 DIAGNOSTIC_AGGREGATOR="diagnostic_aggregator"  # jsk_XXX_startup usually depends on diagnostic_aggregator
 PR2EUS="pr2eus"
 
+case ${OSTYPE} in
+    linux*)
+        OPTIONS="-u $(id -u $USER)"
+        ;;
+    darwin*)
+        OPTIONS=""
+        ;;
+esac
+
 docker run -it --rm \
-  -u $(id -u $USER) \
+  ${OPTIONS} \
   -e INSTALL_ROOT=${INSTALL_ROOT} \
   -e MAKEFLAGS=${MAKEFLAGS} \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies:ro \
diff --git a/jsk_unitree_robot/cross/build_ros1_dependencies.sh b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
index e194ad4155..9f51f7663c 100755
--- a/jsk_unitree_robot/cross/build_ros1_dependencies.sh
+++ b/jsk_unitree_robot/cross/build_ros1_dependencies.sh
@@ -27,8 +27,17 @@ mkdir -p ${HOST_INSTALL_ROOT}/Python
 cp repos/go1_requirements.txt ${SOURCE_ROOT}/go1_requirements.txt
 cp repos/go1_requirements_python3.txt ${SOURCE_ROOT}/go1_requirements_python3.txt
 
+case ${OSTYPE} in
+    linux*)
+        OPTIONS="-u $(id -u $USER)"
+    ;;
+    darwin*)
+        OPTIONS=""
+    ;;
+esac
+
 docker run -it --rm \
-  -u $(id -u $USER) \
+  ${OPTIONS} \
   -e INSTALL_ROOT=${INSTALL_ROOT} \
   -e MAKEFLAGS=${MAKEFLAGS} \
   -v ${PWD}/ros1_dependencies_build_scripts:/home/user/ros1_dependencies_build_scripts:ro \
@@ -45,7 +54,6 @@ docker run -it --rm \
     done && \
     pip3 install -U --user pip && \
     pip install -U --user pip && \
-    export PYTHONPATH=\"/opt/jsk/System/ros1_dependencies/lib/python2.7/site-packages\" && \
     export PKG_CONFIG_PATH=\"/opt/jsk/${INSTALL_ROOT}/ros1_dependencies/lib/pkgconfig\" && \
     ~/.local/bin/pip install --prefix=/opt/jsk/${INSTALL_ROOT}/Python -r /home/user/ros1_dependencies_sources/go1_requirements.txt && \
     PYTHONPATH= ~/.local/bin/pip3 install --prefix=/opt/jsk/${INSTALL_ROOT}/Python -r /home/user/ros1_dependencies_sources/go1_requirements_python3.txt \
diff --git a/jsk_unitree_robot/cross/build_user.sh b/jsk_unitree_robot/cross/build_user.sh
index d0855e30a1..9b3111f3d3 100755
--- a/jsk_unitree_robot/cross/build_user.sh
+++ b/jsk_unitree_robot/cross/build_user.sh
@@ -41,9 +41,18 @@ done
 # See https://github.com/k-okada/jsk_robot/issues/61
 docker run -it --rm ros1-unitree:${TARGET_MACHINE} bash -c 'exit' ||  docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
 
+case ${OSTYPE} in
+    linux*)
+        OPTIONS="-u $(id -u $USER)"
+        ;;
+    darwin*)
+        OPTIONS=""
+        ;;
+esac
+
 # run on docker
 docker run -it --rm \
-  -u $(id -u $USER) \
+  ${OPTIONS} \
   -e INSTALL_ROOT=${INSTALL_ROOT} \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies:ro \
   -v ${HOST_INSTALL_ROOT}/Python:/opt/jsk/${INSTALL_ROOT}/Python:ro \
diff --git a/jsk_unitree_robot/cross/run_user.sh b/jsk_unitree_robot/cross/run_user.sh
index b0b2bf57b5..22ca920773 100755
--- a/jsk_unitree_robot/cross/run_user.sh
+++ b/jsk_unitree_robot/cross/run_user.sh
@@ -7,10 +7,19 @@ SOURCE_ROOT=${TARGET_MACHINE}_User
 
 set -xeuf -o pipefail
 
+case ${OSTYPE} in
+    linux*)
+        OPTIONS="-u $(id -u $USER)"
+        ;;
+    darwin*)
+        OPTIONS=""
+        ;;
+esac
+
 #  -v ${PWD}/${TARGET_MACHINE}_ws_system:/home/user/${TARGET_MACHINE}_ws_system:rw \
 # run on docker
 docker run -it --rm \
-  -u $(id -u $USER) \
+  ${OPTIONS} \
   -e INSTALL_ROOT=${INSTALL_ROOT} \
   -v ${HOST_INSTALL_ROOT}/ros1_dependencies:/opt/jsk/${INSTALL_ROOT}/ros1_dependencies:ro \
   -v ${HOST_INSTALL_ROOT}/Python:/opt/jsk/${INSTALL_ROOT}/Python:ro \

From 91961fd9211dc0a6a823901b6e8f4942f2af8ed3 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Wed, 3 Aug 2022 19:51:26 +0900
Subject: [PATCH 29/77] [jsk_unitree_startup/cross] Enable iory's google chat
 ros (minor change)

---
 jsk_unitree_robot/cross/repos/unitree.repos | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/repos/unitree.repos b/jsk_unitree_robot/cross/repos/unitree.repos
index 5d4d73ae19..12eb6185dc 100644
--- a/jsk_unitree_robot/cross/repos/unitree.repos
+++ b/jsk_unitree_robot/cross/repos/unitree.repos
@@ -25,7 +25,7 @@ repositories:
     # https://github.com/PR2/app_manager/pull/59
   google_chat_ros:
     type: git
-    url: https://github.com/mqcmd196/jsk_3rdparty
+    url: https://github.com/iory/jsk_3rdparty
     version: google_chat_ros
     # Support Google Chat API.
     # https://github.com/jsk-ros-pkg/jsk_3rdparty/pull/323

From f7e60891d26ad773d22eb43ec93dd24639d4c973 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Thu, 4 Aug 2022 00:04:03 +0900
Subject: [PATCH 30/77] [jsk_unitree_startup/cross] Add compress command

---
 jsk_unitree_robot/cross/Makefile    |  3 +++
 jsk_unitree_robot/cross/compress.sh | 14 ++++++++++++++
 2 files changed, 17 insertions(+)
 create mode 100755 jsk_unitree_robot/cross/compress.sh

diff --git a/jsk_unitree_robot/cross/Makefile b/jsk_unitree_robot/cross/Makefile
index e942246cf6..7a05f06953 100644
--- a/jsk_unitree_robot/cross/Makefile
+++ b/jsk_unitree_robot/cross/Makefile
@@ -20,6 +20,9 @@ user:
 install:
 	./install.sh
 
+compress:
+	./compress.sh
+
 clean:
 	rm -fr ${TARGET_MACHINE}_ws_*
 
diff --git a/jsk_unitree_robot/cross/compress.sh b/jsk_unitree_robot/cross/compress.sh
new file mode 100755
index 0000000000..57a097320e
--- /dev/null
+++ b/jsk_unitree_robot/cross/compress.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+if [ -e "arm64v8_User" ]; then
+    if [ -e "arm64v8_User.tar.gz" ]; then
+        tar -zcvf arm64v8_User.tar.gz arm64v8_User
+    fi
+fi
+
+if [ -e "arm64v8_System" ]; then
+    if [ -e "arm64v8_System.tar.gz" ]; then
+        chmod 644 arm64v8_System/ros1_inst/share/pr2eus/*.l
+        tar -zcvf arm64v8_System.tar.gz arm64v8_System
+    fi
+fi

From d1c49acd35f0eb05de5ced7b94238832b609e5df Mon Sep 17 00:00:00 2001
From: ichikura <ichikura@jsk.imi.i.u-tokyo.ac.jp>
Date: Thu, 4 Aug 2022 21:26:24 +0900
Subject: [PATCH 31/77] [jsk_unitree_startup] Add emotion reaction

---
 .../emotion_reaction/emotion_reaction.app     |   5 +
 .../emotion_reaction.interface                |   2 +
 .../emotion_reaction/emotion_reaction.png     | Bin 0 -> 23907 bytes
 .../emotion_reaction/emotion_reaction.xml     |   4 +
 .../apps/unitree_apps.installed               |   2 +
 .../autostart/jsk_startup.sh                  |   1 +
 .../launch/emotion_reaction.launch            |   8 ++
 .../launch/google_chat_ros.launch             |  22 ++++
 .../launch/unitree_bringup.launch             |   6 +
 .../scripts/emotion_subscriber.l              |  48 +++++++
 .../scripts/emotion_talker.py                 | 117 ++++++++++++++++++
 .../scripts/motions/affirmation.l             |  46 +++++++
 .../scripts/motions/astonished.l              |  41 ++++++
 .../scripts/motions/curious.l                 |  45 +++++++
 .../scripts/motions/happy.l                   |  48 +++++++
 .../jsk_unitree_startup/scripts/motions/joy.l |  51 ++++++++
 .../scripts/motions/love.l                    |  64 ++++++++++
 .../scripts/motions/negation.l                |  61 +++++++++
 .../scripts/motions/scared.l                  |  34 +++++
 19 files changed, 605 insertions(+)
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.app
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.interface
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.png
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.xml
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/launch/emotion_reaction.launch
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/launch/google_chat_ros.launch
 create mode 100755 jsk_unitree_robot/jsk_unitree_startup/scripts/emotion_subscriber.l
 create mode 100755 jsk_unitree_robot/jsk_unitree_startup/scripts/emotion_talker.py
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/scripts/motions/affirmation.l
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/scripts/motions/astonished.l
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/scripts/motions/curious.l
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/scripts/motions/happy.l
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/scripts/motions/joy.l
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/scripts/motions/love.l
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/scripts/motions/negation.l
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/scripts/motions/scared.l

diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.app b/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.app
new file mode 100644
index 0000000000..2c59b16a4f
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.app
@@ -0,0 +1,5 @@
+display: Emotion Reaction
+platform: go1
+launch: jsk_unitree_startup/emotion_reaction.xml
+interface: jsk_unitree_startup/emotion_reaction.interface
+icon: jsk_unitree_startup/emotion_reaction.png
diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.interface b/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.interface
new file mode 100644
index 0000000000..044105d644
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.interface
@@ -0,0 +1,2 @@
+published_topics: {}
+subscribed_topics: {}
diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.png b/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.png
new file mode 100644
index 0000000000000000000000000000000000000000..f89099f76c4f0a7af8830f8545782335eba0bffe
GIT binary patch
literal 23907
zcmb4K^;2BG*WO(gcXxMpmt7oMiWVtQ+@(<5cX4-UaVTCW#kIH;cZwDFBE?<y+s_a0
zAMj@8PVUJ($<5p(CnwK2iPltC#>Sw)0002kswxWF008jcD-eK&@-H)XE4TTVf!*a)
z-=h6X0cciH|73Jmm3Qv{@C*MvKsmN-pMQnq9*PDYIxaRI-sW!B0B>(^9{UfD?w01R
z);un5w%LEBDE@)y{sX<W_i(ZX$a<OEJDFQJS=0SrB|2SKD{~KPcdn4(wtraC|FE*2
z9(FEn05x-07dm-!Cv#`>4_0p0_Up+M9RIqPtg0aU)@S*o1HFY>H(jJ%Z`IvhFqw}j
z7%B%31EVn%&|!<gW8x-4qI8Plmz(N?oST=cL~dM~3-h<&gfW+AS7i(!4m7q<yaL7$
z8#+Ru022AB@lkb!PT#VB_4__?&%a+O9rndrZ}V!^e+4c0Ev(Qnl<RjKUSAo<KM>7T
znlu9b6Lm4+e!u=7g66z9Li$g5yy}D_W#E|w>PM3t%P8)4at%#|%}y#_#T!y`mr#4&
z8JWbiA8EJKiGqXtB(FP*jmskIOtr5VXEeCpopJ<y?I2~S*k`$XW_zYTzjn?oej1eR
z{iJwGD)+o)`TZ6<$a7WqFP;fx8S+q{EhGLk_zE4av!0l0!<FGSUi|E5LKwhZcE9=*
z8*{u>n&<atf+YBq?bbYic1c}w37-G)iv;!y8u{GKU}<Q$TW2JkD~L2kQgqN?Vs|se
z={L)MZNEQQ*BmSo9CGo#Jl7O~!{JxU=8MfR5h>&Id3NFQdp$(@kALVWD$kGI-$I(`
zz>UzZW>S-FBwBx|A@Ma{9O2-^sq=vnClB0c0r0H1+Q@fy`AgE-CaYE7w<&vN43TRw
zH)T%(>WJmJEngvI?T<jbVA{shNaV&YUn%iM*p-|G>wqG3;W`R_+lGD>(OJa$kl0>(
z1nMq(CJY=u4PEyaEeqc8k?TG$2_{tK9gSt)piiJaqo;h@Vwpq_nv?k)17E*bOH)cH
zNB)AoYX`HFeH=6;oVBJY(JE+Pk9I5npot7+L3a*+AtWwB$i&hhlU<wa$N9m0x_$uN
z{$TSyG_ScdIN~&L1EjJM3|Jajvq)33N6@0O&F8<+L{{)rPdAHZ4?NSXHe{$pU;2xk
z)TGVP?}T7*DhRnM|I{Zn-nn%nB9Ms27vp+R=)@EXC$Zq>R~c@bP9M=8dEqNm@H-Mn
z{Km$Lc{aq8bakon{j7;7)Kr@0US&x5)Kl1V_Q`J!+*JyU(&kZaSy}-cu4#CKbMQ%(
za;Epn!rY2&wawhT^#MKxkWu{`X=${0CEP1vmhLe0)Pm+_T)&QHWepCo#aSybR#H?s
zkTe}T?l=g?4|yhPY|r8*;*93$@Mr#;Cl`y;IIR55#}wbVf<PXJ{7S>nVM{wg87oQN
z>Aks0beQ+M?m{*^&4$N;s);1k5fqkC)`4o$eB}`l@90I*?Q9bt+?SU$DJA~n)JZuM
zh4*a2FxG7!M!rYbW7#P4HJQp?5EC_RvJa1nIL?VQdjIWB_+0sIqSRSpOCO(*09vU0
zT0BYz5*5%iLcGJ{`)!Q3w=TekBFMyb9tk*wNyvJPl=@gI=TbEJ;|Hr5kczI{SzCdS
z39hDz_Y<JoB*}7CN@jo)8p>|)cF|#r>1k|;HN2KJssp#QLll<BZsxIRv8Ft1i$`Im
zyczIu6YZzFkZi%-isqTC9SAPe1LeTOBh$<(77Czw7p$>tnSA4&si)tg?ghvHdP*Jo
z#wY$l#tM}FR(8)Jzt5CXMwZBqj#|TR;SN6U?}C@aPS$X`@!-|Pisl!ID$U$B`$%<K
zojg7CL#FFU25wh<pItF%?{n3)@VJVOL)4vW@<NI#(An-8>X?=2f5A9aw59&BcV9Bg
zO9RSjuME~bN(EDuCL`%YI4%GBX$S=eWwpYO>#tLf?e<@7e(M#VTf+MYLobvKW=_nA
z?SH|_L~9+>*rlkZ$CheKiVmeLcKASG0FGWZ4upxW(eK$-4sIA41Q$Fz51Q5B^;jyX
z0SY)W6lBY^gI$d*qdu~>Tu3J%b;vYH#R-4xR*U_h3@m&;nL)#fzwytuL9?6tY{VG6
z<Bpt-sfwxvBDZikj3Qwg5%ENe0(=v9elH-^fxjxMTNbZ=nV;eu$&N#-b}p2>_j}4Y
zXpCs0+*y<6qR)f!ee+{9m^B+k;QY>Ws-lin0NJV;SR#fud>F?Rds5vt&pZh!*`wEt
z*~W#BO_{2IhCQoZcsY+Q^5zMp7H&(f!A^c2b7e0@B`EXDq=0FqtFO`C@KDAd=0nb}
zj7Z;~FjTDRuaY|A4iv4nDu&2WBFh^co!U9stp3sCL#5CEOv`*~W^?t0+NBHYWs8^Y
z2%jRad&LB%52S3|sTuox#pnmB`iPi2P+6NYo$jZdz+o5_FvH6uU}Dt^XUqf872FU)
zM=SwaVY7q)A*_Q0FzRczBXZp?Wm7Wjc-uSy6m)?=r!@Jk>;j9mK<>YxA2Pcas`(zd
z7CO5m(1S(@U%Su3mF82S_L9iIG@8(vXLLPKNQ}lGVjH?DgV(tMK}p>%glXbnV<KtS
zzDtQicKvnIz5FdLw=ZKndDP{|cFU|0aJkj<u!wvqVH1}+=aY{ODYnw`Q)9Gd#yJ<9
zXH03x1I6K?g@;3Gyli*xFo=oc%GLZ;K2o`zwiQ3?R9ir+snxzKs|9f_Nt`#*H(*Ar
zESt)Rr=1e)*9MI@^Hx0XR#!@3{ni9i69R%sN>s8VNJUl9u`>OWXJ7YbDmuHr^Cc&j
z3N5oHFci3(lEW29&|}8Rz`aZPN^kaiNXl_@<Ojwby(9!G{;uM=`c8SK_*3}1q`we)
z;Ya-|gn_!;MXsjmY13@2M`M)^j4k$|S#B1t1tZJWl|h0wNOq_M$qXgfZwjN;F+q{~
z+AL(*qazIq=BkV{sq8!M*&%z&8aTW3*ly~)@2H{~?mXcRTrq?+KW2I3rR{h`gpP2g
zdco|>OPR|JkM-|ys_bFKdNSWe)uA{{YK*EGZX82}e(9C388kI7(o&H{(-_`r7bwkv
z6yxBg(4$b@OVXm}G{@Tll}CJmm;kO2)j>M;bbcbi;Db9n?M0-_QifYGdQuD&OS(78
z1zW5!0r)4Hus?U!CyC)bQlC;K{!PmAO5-%krFSb7vR%a(QcgD%>^M-NJUF+5UuDxE
z$YWi0x?!m5ntxJ+C?_z3MS+VV=PiF_#6ts8p-`}D#IfVccvwS81q!;(IEHq+T1w51
zlPs?sz2cdfU7JmtBBmyyS14KSWZeP(?E*P8sTS3+E^cE(^%lKA@nezj?J9>Wb~E%c
zxRQ4fbY1b;`TboV`&W}*Azb;Tgs$2Gl-+P(G$H86k;(kdFuAL?5Ch5d&qa#H%7t0~
zF9X#~{#-(b>vCgVlnGth$N+M9pHKp?{|8yTwy4rf`c`CzjD^a#=mqmE?vRkYpL!7s
zT}E?V#<XxbTfX5MjUvsIn@<EUXuqX^jjrYT$*Upe%YqIcaJ6qd@FI2;6;{t4^b1Mo
z>h9UkQ5ZPwl5pnFkTkVaKSO@N-R8~~Doq}O=7pv0%vA*K(Py<&<DTCvcDnI~5~by#
z;-ybl81#iG$BKtj+2p5DTwZew0p<?7`aN_r0W4myoFBZ3Rprt@y804=waK8yiIXpl
zxUOU1y1afZ1&@C=T$6KT@gXeN<>#0A7A`{#f95{#f-v^iDtGiD6+}qpGg6_#OLThz
z!^mz85c%gi;r^pv_UK9Qb^0p5^yWM58_|kA5Ge`|Aqv*hYViwmHo&i%dJOwQ2u^xm
zXAm3em)?@Py^Q)7TwIz;DNn2hLd;d_M|UY_L|a+$lc=C_{dJ&10(Jw{x<{O@LrdlX
zCTJ@e7Mybeg(l)&*?BK&Ujp-mZav<WvA=Dj`*YTx^gt+pD?b;iElSw(CRhHFP*(v^
zZc1^fKST@^+w(xZXc`?dF-jSKTisy_DA3DYoO|jQ>RRhdiM#T)fF?Y=7n5*IIwV08
zd_;R&$(Y1-3%Hoe-v^8D;YUg=enAQ7FkI~V#vA5vX=%J_RSM43tw?6%zrnzZ<~~Ue
zKw`dE*`;e&44h*FSIiJ5J-*=Qc+|vl*JAoeYVyrPuUEWg?6s@QLP`G(eC};F;a{82
zaY_xKr)=2y$hU$LQdMrZ48Ex4)GrRajxV5+YUEFrNDcWIRNiY-4;Qch{5Z$tqivQ2
zuDq+-j;V?A`}H~uQb)929G3L^DcVGY6Q{_TLJW)X%+Ut)=e}EQ|563S&H^%|tno?)
zmSY1`Ea)(&wA4=qq=x09mPi0rH$STMJG8w79Yne`2V?f~n5SYuNov`U<@g~JM=`u<
zB5<<x5sSQ21tXwvZn&H(1A7*LxjF1eQ=C3fwCO%%{;-fzVDe6a<>$w&@kwWmpV~$9
zTgmrk9wkJ*Ff}q2@~C7v?5s~WVXLn#f4&D2LQ%+Kv?dzXJVcT#mD;MABpnMDDtC9y
zQc5E6cRx7=tyxE<El8S6y4d5ffoK~-NMr#RMJ%s=F2are?(vjRiA6tK=G;M}EJR#L
zo}95sHAetr@0oS|0f)N%UkBb|%r-EMWkor;f4;p)MCbm!P~6<eS|S~|g=1#v9Q}r)
zcc?7tOKf}vJpiEf2V<{a@WB{A%xer|3F%#6cCFo4&5pzL+T86x2QPbt`QLmBj!%r5
zfeLc#oZ4Zs0=kP<$lopIDv->3gags7t-3ymQDCL}0gMRSogh$=?%D{y4hc4p)p|;|
zB7bIF#^~OyB!iIwFxXJ@n4n^_yPK+q4zv4{<196>I|MKULmfkP8$xn(I@g{L`J&^v
zNFB0k^f#=8G6*yA)Q7AI_d^6VQg+BFByfu>V@(v(M#BieIwpfjGA@Pfmy5m)M%Y~y
z>6lf$y%s)sKJcF1vlYspdlct%RVC)>;X<j(tPlp45@5mEpG)IIhM($;{U}F~n^k0{
z1l|^#D9+ymkGrnc@pi8s!El}#e+-<o_%0YOHaKE`Tl5oMX?j5A`|6D$Wjn#S@l>>q
z`RLdC<$?tukgE~E_6GD;zx*)PUMBN>nzdfR^pl+!`y-`JjndmpHh|%WDkSPl7R+}>
z3ZkEpJT(i5;vo`f3%p$fAN=l&_zrFcDc5p_RZx(q$kvdWtL|l1u7?oav55hkIn4*F
zQ@>|LWyaukpXfCv6(QB@jcQ+2KEBwWdCO`5E?A9_E{V&Bq6_V;MVdIuDDdV~VZO1!
z7r|5m0RW<`V3i^ohqKQG*Qm|i`Uns5Z$WPM0jp`g(j!j5IUbc1roF@j#C09#W_7kp
zr1#6JsI;KD4Kq2saDjcPWJgn*)(l{H08&s@<+tzXX0vA`n0TeY+@WtlnBcu`x8cdg
zOIf3p*FI;>8V%jIMlea306dOl>vJ$*x67nc4}MOMZY>uYFkFor7c2%Tu$1}0*bmL`
zI4K)wNCubv+IMrOlab!}5AQPs1GTKLA+`KET5cLra5QAX;NToJB%z<MG~uWicfM7P
zf<1=x=KR+mK^6fFK02;ykqjlKA)g+=b7H)nCuc&4bXXfv-bHuyVq20(PoxzGwP4uZ
zwg!$<80V=U;nNX$R|Od%bR%3WITSa%!DK)|Ws187B$zNorK%nyB+G~#g$WY*HN?${
zqG`c^=k1yl-n7qmZ~_=CB-MJXY(mEP{bbtlcygA8I>)vkZ+;C$`SlsxrA=C`X#{7z
zaSE$mxyL>0*?%q;kO>ysPVhv;cPCoZYjAs;QVP-{-x-f1t0enwWCVe9@XnYR#vtO~
zDb=A6^dYL9bixAztd*rekmezYVKvoJ1hHv^u*M7dRZ>jrvq49@8+A(CoyxHA_U{Us
z_m?{}-MnWP1GL|gNDDHPNr^9$4$^J;n04{kJ^{b*Po>@Q$*yWZ+vrqMVspwl@HzVd
zF?P34&}O*QWQ~>(o2oQULHVqU8Rkm+p(KUpXK8^plbwlfvn~m|!6wUx${OX6Y`yo`
zwqr2MB*@f>qG~E__z<TjSN~wj==N+8$(Le%oS!$HLQL;T!Nd28&VK>v#d8$aJvpLC
z1MOL#1-6jwYR`vnh={1-=6iSi-pyZgb`tp<>vA}1n`R60QFM*_>lIknL`>pEC_QZI
zk9Gp8Aul@b5r5Tv+P{~#8O&&$F|8WvZ$CzB#HCQszzh;F{iqc2z?=RpIf@7A(Zs6A
zN;b$~>mDVBB;*6O0^*s5W^~uOvj~c_sw#YMv`^o<^v(?_*Jx65gNZ68%0u3C@U*o+
z6=PQ~hZ<d{KO)wy<7DMDFUVBf9Dc^jGzyv8G*=eQXjL(qJ+2XfqYt8A$H}8?wB0}3
zTCxIEI?SI2YLaGohr7pS3F$C58V9R?H3l5zo0(Z90!_34$|iyHfEYC5YCK@{0&&AT
zf24mWhx<=IHWrcc*8@fADzFss!C;boT8@&Q7(9hpjRHw5LVrlK9GMb{oP8kR6(IoZ
zB!E$`GvnvA90<;-vyA9hCFJpJ)vP=U#ug1F8W7p#438rbr%WJ+UI=xFhVfDHuJFTx
zp1j|a0#I^s!+~vk4bTC5GFC-<bSXA8d{sQWP>HVtvK%xco(}2T;2mS0Zx{+aU_Q@!
z;~BQHhaoTA!d<b$Uo*=sj=BNb>C5O0;RP42G;CY6$fn$18}#tdUep(B+;x#B09l_}
zO)>{JIEx>I<O7CmP)BNP+j1>ti_n9_69Gjt{;ym@B!7b7WM=$B9fLX0$eh~}JrwP=
zQA5lKDaZY8z3@Y%N-ue^2mxiB1+jZf-ZEI;p@jH(tLro&n44G}(*_^+&t5Rm1LF-9
z19KVN{b5J<L!BhMITD#IeZ_Z$jo$L&lNGkhH1=yinmd$jM7`Z2|9$9>Z@c@?MHYVx
zX`Z!(Qsg48GrgJ6!K;-?Xkld>bbzs!05>=FIexJ}^S|Q)4#MT_;?NlPSXJ7dv>oK|
zU(?75wGn!+qnG!6*5n%F=TBq?Q3)c7mqjzS{UWq%)wXUq#x<H6lZnf+aa6K4poDi%
z%@xM9X~@Bu<)eS)|DGnzM5s1u4-*k>Niq@^51FXx9-<aNiBpjVEX;TX^j1Eh68W19
zU*XT8%Pu*ts|uQ5ewVIQ&Q{JNoJwUI@{A~GXh8YS@3|og%a-xg6P}thh-N}d>t_jL
zB1gN%kRwpr+_{%M`luammF^pssO*kBELx*npsfYiox>+ZT0~h4kCPQR5k#NUOVWvd
zk#fxMd{<+?ATcm)s~ym>9ivD`wgwa)l(}G4SoNsTBq}~~R3FUM#5;H+iM8;B0Zj#2
z_^Z7f(;aGBni&Z_noR7-xHGRb@#2qf!6c<v6_YxgyCQI8j%T)#Dl(4!P7`v+n>j|a
z>n8ukI@9YdI#ihoRfzE^dU)MPhO@<l0HVY8w7$R)3yOKpE`whLEMKFC&xr@8DPZHx
z<pHL5=&Z-6>xSjmY{kh+kmxHp%i(}1TqY{4t*`+MoPrest}@#0oC9ZHWbY)oRpyq}
z>$oM}u-^;MZ*A<YhU4V1@2qg9Rh~d!>{YDV7X)#Gw1ijaB+BE%XjC|uh-K-b!6sC5
zR`}o5FPUL-U{5#U4>JKV`QFny$UtZsAK71EqtYFFJ}or54}&@cV~>1(Xrh&5LX4c{
zMm;=ubCo2E*U^8MKXi|=GGR7<J)oePADLuatONuGq_4r+-6quzwDPNuc71H%dvo$B
zhittJ^f%4PT9j9ql)^r*nAPC@f4$S{3OvLtVgiQN4Y&}DjdVjRcoSfs8~Xh|YDZXB
zf$36)#5k$IjzyVR*?s?aeijku7Im2`klmF>m%FP~0v@}m!lqz3k=#HYw9y{z2xBfM
z#rz`=0r?)WA~Mn|DU#G6jHr^#`uMuy($(A)>)Cyv-@akw!l<z=Z-6A%J49tMLy{xa
z90d%o?A`&G{OWSrwN{a`wc3^-=f^?ruL1;y<Y4g;?jNE2dZ2|9{P%;_yM~-4QgOr9
zD&9;ysoTN$%D*Gg;7=0(z7JS2CGZaFqy==js;WPPw!P$+>wvEJ=hy{U>ZPIY616O)
z^b`A+K?vP{8-&hTrmjI$mQ4aROx4=7@RRBhZHCzW)BX>o1gz?`x6Xlx;bPx;hHg|8
z&yYv$U+?d+Ws|I<%rQ3DvDfY?B6m=IxY1(1f2Q&!=UTsDHMrd|Rmg@!dz^m|Hzq6i
zqFv&a)pz4xTK2qdlFR!&a@*sav<65sKZ_ZvGFmXF9Ie<Cw1SZA!M?;+ScVADvc0M+
z(-NU>!2rR_!omlz+{9gv%y`r2-i`*li708%wqF<Xb`!$_sHMbf*l`w+vxUAs$FsY*
zi?fe)6QMk+OX02E<nSWr>*iV)-H)N-Ek7xABl&(32fh)3^00lhpZ-Y3O8m7WYVnV{
z(pmZr*e=a)i;o|m0uGQ^yktVv!YKVmGkG3&T?;#JVfj3|cVd}7&Pr|$_q<^syO;^k
z%y9%f`fk7mzv?6BYke)*-FTgZg7d_O+v~KQId_fPf=2m(KcIs0KA``O<*j`9@dCjS
ze1s4%#0q9i#J)5+Sb~>P6?Use-|Luv(XRd`?7y6R_Okzs*4etVnkRlnCz+iv&yCiw
z40}UX!_#_s1Hs{uypR2b1VR0QXS?0Kqux=B7IhA=K$qb<3^rSSm=03X<OErohT#)d
z8$tjZs3eVGdBx45MppQMP>mH>+XTK)(WSuR3TS_vtK1aj>_l(={z8Klk7LJ>(R^!B
zQWua^>V4#_7ACmgg+F29^KQVd%N}G#^@3&ZtMWeQ%;*Q*;)~W$5*zTN@p)M$xEO_)
z5EmjDsbydD+Ude8^G(ldJOIytIOcH#d-uSK*+PlSM{yHUK>8m-vC{+ZUU%HCAwsZe
zs6TCojNP{N8NUfSMQOGAaW06J+Ks2(YWg?l_Q~WGNI(#pYil-)OveJolb7AdVv*fC
z*TD$(i4~IL78ZMQVpZqpow0c@^h(<H%O&nG$fp62ZusSdt(~=5!*R!Zg!e3KTLx5Z
z@I-IW>Wuzm-N)U-v~lumWHz`lzajqUGnqLriiESg@9OhY))u@JuB&n}Tqco4VU)Sm
zXXsr+Zt_aHi(m#5B{Jp4SeUio9a^z68XXCilAd{Fllw5Xtbq|9RC2?pW_tWK1-ka|
zxKPQ)m;q3pl;CbTc@yj7B2&|k#9&5fiE<vRx{JE${)@$IPYrn{2baO|0G|Gv4e4I>
zfdRd*=a;<F7fC0Fe8`YFjY{G#rUH{Hr~O6WYSF`}Ckm{^VLMZLQAlu`jFBe${Qwge
z8#9Rg^w^9lgzI%<x(FFlf`-F8xUU~@&m2P!0yk4U>tSldEih5^79tNskm)L`MM;$*
ziXFTKgrxj~R)pqq01E9drq?+AFOB8fdctIYY%ujI9TiURYgV0&YW1{Qbl{u>W9{v3
zTxi3m22aWwzsAD3G>X7prn$j~J5CBpRlxV}gYPi-hL<8z@S<uq%LwAMTX&io{&b&n
zTY&7`U%sUOEE?!k#l1FnaKl6Vz^Lmk(K2|rJ2m@7c-vRueA|=yOxb<#y^Mq8y*i3I
z%kOtgznkZlJ<liUM|U78S8*iEu|b(K_9RrD2*J&RcV&IU?!06OIcW4Y>eKJXUyV06
ztb0qMSRf4A*sL-;=IJI!rLkjIgXq9Ug5WLbt#UpaixDcqk{+Tr-9_=-JEE_gWFx+F
z!;a^1Uv4eWn#Y?dQ}V@9WuNh*P86<9(wbtud_C+#MtJtIdFObb4!`m*WNJyUXwQR|
z*1E_)$=pbu-Wd6q^_^~d4#Gez8W|!u9q{N+dhdgodUY4h`pW?LwGH++Qfh=CbWCW+
zf>J;rb&0bNa{!=xWh@VF_h(C$JP7mymq=$<?pHfP=B~Q+w6DhEXm#seW$VDoZg)pj
z&X4=6t1uXp`Ft;?wTmuw*kHtsHQ=;nmdZKn1ZB?*wA*$*8<1SXIu(DW$e8;vdAE%S
z7GP{_?wYy(oS{-P^)zH^=Kl9x7$AIs>m!}qiZkbp2A%A?2q-%XARp&d6df@)!N|s#
z)BV8dFw#}b@{_1^fUs2i2~FcPOR~yj_WEdTjtjx0Dwg{jI;O@Qw=x;WznvB)S^}SW
ztX)~^L^iU$zK6Q--UHfC(yF0}vt-J5%2h-L$m0C;1*Wwvm5HDaM6)nYdT4D8OHpCB
zQ?YJID*!KBh2>4ZP<#&3S;Tw2F>v`Su-WBz;j=+uh)5TC*1kd&5A(Z?WG<qpMvKJX
zYDpgI!jhlB8UQzQxZJ1<4U*`f`6H})#f$doDtL5rYa1eilM83T+`7u~sf9XqnX@=f
zg~KW9z)baND)`gpw2EBf3sozBx;G=_kF4mhufB%L8I7Z)y@~qp-BijWyqQ<YnFs|d
z6I!|{pF%k4_g#hZ19=Q;3K+YnGEVWJ7ix=atU-U2S9ukDCewe)C1iPF>~r4R9LI=0
z1uhwdR{LLj2Gh9+{lF_&Y$crs&@n4u`Uuly8dT2N@$Do?j?G_@OznTaS029PhJ;N$
zwA9wkKPRpN9P<O<K((9e3Odq5Hcj`7Xq!-9kzM=teu?|S`RQLYv76g9Oa$MqCTz`G
z&F}Tif2N7M_R{l`(*|{GqKPS>9K;_0N*3=w-Rc>$EjKa-mkj*r=W2^!W(K8gBbgNy
zTF?Rx)g{o&%f*p|laoYchZykK7Ahs1A0oYbu{k?AG>KA_E6{C4#Cf$Z(nK6J&af(T
z{e~Amuo)}Q5okIE%P}>^a&zQ=4Vq8<6hw8C9iTY{v}?}*I9%Yw;w0ICivQ_KQ^>;Y
zaZMYjg8*+>+ZKKfX5d=tSPf<aIBb4v&oVjX$Nf~waGX0dq15*6F4S{7rqXP3%4=zm
z{tkpajO$jLDgzgY;5qF{V!)bf($UhZ<VaJwB2M}xL`PJJlJs^mzNPQ1%6|>_RQj1h
ztlJVvHv(dv{_x7r1P=sW4x<|nMvKWvI>JJW3O62Iu-P3$2AG{B(;Yt*GJ{hG=4ZOn
zrKAm?eulL*B_HT`H%&8YNTc0K`vv|?#}G|LVql~T<u5qL0xb=b3R`V9b>{VkWFaLk
zTpo?{SmP7;mo?xO?y+HwhpguDJ^hqE4Zh8J$$b@xy1f>_6_H4X3rG%wSKhm(7jB$A
zzopD)iXClul%zwV$W19!lEYY-VB<5-7S<@7nX9VE;pwmaf)v!W-UxdRz@X%3-F6^U
zf3pqP-OOgIMbdP<NJf_z5WpfUA8t_6m1THa%RU#IiM*_`X*V)n`rdK#keL?VoPS|`
z@X@dG4?vUk3yDyq?DtF3yWGQk`uRiL^d7omvJeLvIc6|G5u0(lfmyqOr100NwF^-~
z#-tV71|Jot<Hm$1f^cr=H-xX&-Rj4B%3R-K5<YQKN?5lLA>K}siAOFI1gKbYV*EQ<
zlUrGJf8_vQ)%A{j3gWwQL1$FswoFU^0l?6RBD#-MBLO4Wd*UyzEb137?eRym$zWYc
zHb4i$wMMt-ESJy`UX6e1>>77<74?bENNOx;y5#R2AG>W@tgpR)om#w}v`sZ-5n}1{
zSAP^y%Qu*aI>wfyjo>_OCrWFY>jqZbwlpU{G4-%c|9v9QxTEE(y)Q~Lu(GeA5_mmt
ziYiz-7G9qa;J6zAa8S1Nl+c)&;3Qv<FFftuu_h5sbjxQjOsWS=v3xLVL<wc{QOIiu
zbq<yp4YncVw#&J!#Ro0$J_=wZUX`6;`+i!>>~W2IS3*5FjtfIARPgZClg@YL)~yfy
zvgC>S#t9{9_%LaAfbh^p{xai(v6pTVqpQVkZz#HFqK-!+KWc_UlXAFhvF3x=V`9f*
z4x!4{hmS;~#VK!O?@NDrY><LFzHY`Ji>Q%OSnF#peS)ZLyJVl%pz#QNRc*n^@dM{b
zoa&ZPM^-;0n*Ml=`Z5dNmHoaiPSrQ#uAb{5+at2&qYh&#ZjLx&4f1iFk(FgOPw(b^
z-)V5kf%Phv*~ws^eOcxRjm^T;s^u*Q6M#*XN%mE-AwelgFFXz8*ARtmo`OfeIG9v7
z!ET9<Mn*$@)`0lzR!jKo!y~rWv0<iRKj?PZw@~9CQm1Vk=%-=)J*MF1`*tg=cy_0p
zH|W)0NzvHGq%vBXc0X0m-q70W&=k!I7L3#(LV?ep^8)26G-S<z4+WYtl+hXL7wYUa
zGZZ0FIGAs#^+gbkb>zYkypg!AOicV`GB0sd)RChG|Hw|DlyJ*1l0XdUj8|Kp=a9JT
z!PP*C1H#(qgDs&WG7{8%<9zIL2)|tY$^1`ex%HqbjvUld`@1n<_Q@C`b$9(^9qBai
z!);$EenB$20>MgsvCX~6=TS9U>A26A^}e8_4qm!XrHd5IxdOx^oBWa^38XV>0~dNa
zd<Fe?_&Q^_+3>?Syu~{I_Z#=kCPe%MDr+|RIJVUHxFs~B+?C&_nM$(S9DSOAX=Co;
zVaY3h)IT27QhELQT!7OCaMs3|q`IQLoZM{w6o9w(apZFw1x+0Mlp_$>`}AbM_@m+r
zq4Rs?NN_$)aW<(FMN+|eNylpRs*$=f-QVM%Y>Q!Xhv){&q2>{)0EZb(D~AK?!QLFc
zW45d8qc&@Olv+f?gkmve>e_j3$C-19Lp$`*r4325o-sYDgJ5lh?VVzFD4y&ab#2?<
zs<R*N=8W^iGx{g+^&U5SAf`Cgl3%hnWgpWZd5Cp295-TM*$obt&1u;!%3%(qGKY_j
z*4P5sjpR(r16Z&lk7wV30udNbR96Z9$G4MOJ(u`BPhTNZwXF+o+=ZGNAJ#qv{qpWn
zRLKIsWny0CL0pJIT7i<U)qv+qIa@~){Igm=2_p)>i)$5ctPKXOV&U=}tNZZTRL7hV
zUR+Y|AwV-ACN(q%VZ?dSS9(}Iop>Hzgxz_Orxu{Rj-4Gvu1982Xrs_IpWmKL5xcs}
zgkM7QMzZ0@gR)oesa}9iZgiRTBYtMdtAtrNW`dvh*TFjTeGY@p-GoJTjq4Zp<veDv
zj|}BVd^K^bu+*Q&D{6owYSULr!{*G^$;kVO4+cTH8+ZZp^tRpus0DADw1~P|H&yP~
zAHRj%x@wIU6a*~Fm6xIeq{51?k?9m<1u)V~zG#WmSR5XynNMZPVg#%<TpU8tpsyex
z)a#s}Fdf`L;;|ezyFX2kfnN?@r(JeG9Mfb*sfNDSDYRS_PyWXMVBCK1;xR{Q+9Xwo
z@I6m0$q#!DJ=-{cj|Wr@ly|jLw`e8*b2RkRi&Yg@3Bg>n+?GB*Gy##&Opc%<u|*D6
zN1|7BFQR8k;|^xSpib6}(}Hzh|3+ZErbRgae9YcuoMoj(o0NP?nQ27SaeISYput?X
z>m1-a7b{zkwl`(^Y`KK<dGKVod?|OBKJDXX!O?kNp0kSr3ZFTawmf!MWTC0x1}V-x
zOV6S<VAZrrUt;7{IFZtJ7~@YabUlK1d>k0grLzC{_$iEGp{mKphaw=QLc@%|BQxMD
zxmRu!;0~wj=yTwJot=Y_JDqfcs_WlESlC($>-O5=(o1O#b1bWAl?fxs2-0|;OWK#D
zWgO07)j?N0J00N;F}2g{H@TvDclLKPxd=eEchz`7i%sZQf#2C*o9m4XPqGO%@D_91
z!)*K#QA`J;$6FO^q<InfUv8kR)ZiW`u6PO+JnUfe*}L|XHzXWcpPD_XIL^PVcDxua
zw);C99C9>`;5`GC$0fMQ(%$VYA2=eayaisbdpInW`(ueP6*1_tld+6Pc860qn(rYF
z9TA~r)Z~!yL^or<8DiI6>dz?fPh+tSjn=n}uGby3aBuLqqW>TYVkvUK)|WyCE4eDg
zDaxXhZm37EjU9l;#ofc0jW&HC(TB<Q_K_C5s;UWE4=@FEEPrm0x;iCW0l^HO<r{<6
zYcy5d!63DROro&o5tDxhYm-9-3LfxS-VKTOr=2fK+~<RQ<XI5YhVJ8M@9rJ>jq%AB
ztbpggu#nAZS<8)R6FI8L^u9qommjo2Px}b?YxTRGjATGmZwcDGTOdIt;y47*qX#d^
z!pj_HO1A(!mD;wSe-mSL){g}j<Y3Y*-HJFTjtu`y$mw4Hc87xX1Bs!CZdCCy|M7{D
zC)hqvaCG4%`xKljb@Zqb^WeS-mQ&G)9>UwLkdjoIeF>m$TL0*}DF{J<JgviGM+dJB
zThY!`+QdPwr$t>j4;Y<Ro7R><*ao_@Rs-*cGg<PxVxpkXI#c>t2whz%#u)NcE9`h+
z!6CQG5Q2LqDAbAnR>+3n6Vgk%(dX`qD(~QxZ@E~sDsQ9t91qRUa$0$hqHb7qf#lQ<
zTX8?c42!}~G*yg#9*>vR1F#wpC0_^qpN>iUnpP8g;zz4vwqI;e+1Op$?!`rU9t}06
z@4kue#|86h3LdcG9_iU4tocD^CBI5Ckyl+oS&R}|f54W0hi}%QBzMH|>TN%jEnf=O
zq9d0*@)BA?&$81^1=sZ*AtV~Z=6h4Eu`gfeEb{wrx?;ukk>xZDIW!%t4PU8K*!Yhm
z=2<Vi1a!FeWSjrayRNZ%uKv{;$%JQ7rQ3=ay#0$P_kPshHDKzCnA?mDK@F38Gx5H8
zScPZjII0EcI8YU@0%fV6+-4)nJt2+(!BLb7MS6Jco{E{Yd8<lF<754rrC73Rq*-d5
zM&HZU<KiV!V5Kr;ZF@iU*!JZ7QT|;0yb!P+$3Oa6{<W+Q^=GRdQ5&D)Yt@N&%lXy+
z);;f8e_p(~4_~6>l-eXQC8rJwS>t{bb~}6GX>OW|P$MUrc4zxLX3m8%4=sS}i-uuS
zhF$`tXR>v!UXpI9@M)qt-|O-zq0S<23WBWIiu9qA{BNkDYgwH6@C?@r=?z<+yT_TH
zQ%A&Z_UVkP^M@TLj7$jWo0Y0G=f~HhxVW8v-sS(Z=mIK9Xy%fWwhX-)xZhZWs4s6;
z5@zT;QD)+Z#}jLI_9GZ<g87B?vfJNN(*nxf=*|z(aHIqpSzS<h8VR-yjWNhCz=W%D
zY?fkCxDs<%HZ!u-Ct0N9FibTEHSYI-l|6e{is6hVj%%3+yHe{f>=LQf$J<_#upC~h
zb+?)QjaXTqGj@{KjArqdv$wf>7NSO<NA+GCmYX&u4863zLfx^5qtnGJ&Oo+a2J9At
zEF+v5_O>bw4M)fUB`(r%li!iOXZZeEn*R6jj(F86NFC?bdSIY&GY5F@?+>zs>_8jk
zhAx)`wjb&aqn70zAiuSgqsokzO%xd$J^qu)&$Kj8kG3$BPOn=@a~~^BZrZ)|0q!>X
z>_A-AvbD6=U&;spo2}ZB%pjE$q-1t9O-dDzVM~WVQ4d|R-wNTIpRStjBX3v~m8DVP
zf+*N)OmFdBzf6_lni;NRE%Mjsa(`ER%hIYqI_`a!`{Rt7`h58zUip<LwviG?F>;p5
z$HPY3t-H;h*n~&2r;V3H<ZmpcmsSx2b#hh@D{5bTeWe1Vb)Hk{_22Ajd<r6Ts^GQO
z1a)LdxT?3wVtPWhh3*2=La;{B7x#f)7ESH6uYqRH%c>Gl(>#ivmw@Yeb2|wXZe??L
z7t@-@R?mL7<?qkrlA08>o+B%ty_sOrHP4|rh^>X83}gqx+5+`<W%CHQgA-}vv-7BT
z+K1nlY%4X#m0w5R;iF|;^du!GAK*fNq3U*<nn_?^)}U5RfU^H=?<f^~07<s+-eo?i
zGc}^fYkU<d82l5gG%R2J>IzseOziBD0{u$}7gr82$c8f{wR~KL=>DVIi2nxdkk;7W
zQp|q0GWDOhvfQ}p<2}r{VcnM0!P3V;tDMk#Vgt)XDVpg%38t{Ny9W8<Opx-l5H<Y`
z63SrVni&mIQ1Te#=qysu#)GdCJ7Cp*S-d|8^?HlcaFl?OTCm+EZ$^5@LEc-s0yRUI
z0nAR@_So~Zmf+;_{FJ%+(`UVhcx-s_WDOt)y4fh(m@a!M4GL-z|7Z1!8Q;Yv%Ju!>
zq<*6G{vJV`cQSdoeT7K=fegnkW%7S*I3m>p?u8aMIl+GWjSIdI=b=@go+1lJxCpoe
zS)u8%<aLA!>20(zV$HpQazee4HEmxps$Js}{Uh!P#XBnrP>P*gEl>zj)mce^Uzl#c
z94zVP5$-x`w-yDnh?I5@3<gTM_DZ+>nTMy``kCE6BeBxBB@7a%b4qWrPQR?<Qfe;6
zB#wEl|H<N;bmt;z@-~^wLF~<R717cJT-LuxMq%BlVG2W7OUgB`v+ENEI^UcGd(9zv
z0d~&HUeiy#NAWuCWH4OjaQS8vyhl4k0Jd)mvW^H1Ax9_x3aC(H+AQS!H98hARhi;w
z7V;)m@D9mN2;9nY(Or*&CviVmHZq)4XNgCz(-SxNiU=mZuQ=ka9&Uct;C=t7{GV<)
zYH&f`?x$V8LM_VugnpR3VM{ocd_$uOI9<iirs<O!ihK|O%c_gOxs8`61Oc&(nQ^uA
zZeyk%*99CZTrz$AMwLW;6@&_NSUo)P7(6{U-n;ZV7BP-DGNd!s!3ySdOOw{iFEd#y
zlH5c1Esm>*?tIY|DlFrrHvbOPJ@8@`pBBOCkPA&3FB(P`vS!d5vq7cMCEC3?<534~
z<BsAcux&5>(96sL5-F%H-bx1c#0A?{&V$uSTnn8M3SwmxfmFxil>yEZ`MYj4`*+JQ
zugHe3&X*5sl_9?kzU#xh-M)svwWa-$m!PPAzdspZ53zt=7fno!l_m%@`z+No2I1E4
zsLy0&0I(8;r|;%oIGa`pakuTXWq)0>Cg!owGbVg9%;oC(6L{i^)d2I<cMK`eaVp>v
zHM7rze^u5Q!rAwOgb7dt2BrRCkGRxCpD!l|Z6|@hVMuM^JBoH7D&o~hyc~fLe~o;T
zN6R+j(>(;$HB9@`_VN~AEa>L7gw3Nq`o8a*(6O|2uKEI95lw4Cx(>^4O24%lS1s2u
z2`WKz*W$EB*dO~)gk*BiL*#xj{4z{*f<>KxJO2!QxQ^6tlh+glN`w383qrfdTb?Q3
zU7)qxz;?F~mknAsz5(FmdcH(Ljs8GMrvfI7se@x*Eb~gN9EEUVO=FaAT3#Xx>a6YK
zQ2<BQqi2t4r=gybUV}GiJnq<7rxD51vdI7F341p1rKZp8ZtABKV9sR5C}YjF6zJuy
zem{q{_(Z0vCf^9}pHtMTCir6?fDX)xUv8L<3G4|b%_m5!G9)?<Fgr~=jycb9Q_CDN
zx^A>|b)O1aS(wKk@&(0UcaOOK+m2Woab_XiuzY>qmxZ$I0aGX*(HU+-4@w0ufT*lf
zb(I}wD)rO;;25x^mj|ECft)Xz1_?@tBcv`5d+~EKV?3ttlgk-nCD+X;{iSomXQMKh
zn#Z!-r6!xSz%?|9GI#F(Ruzb+_Ys*fU6m?2+Z^W%d!qg>laKBTWs(@RO8E(utrFZc
zkSz{6e$}`$eRvOqpH)~QcI{*C=8<L78uV}|ryMLQ=WyW}+icOKg!_qO6O#g{Z@ZvU
zb~tK!c-Y^u#37D^r3M<y!EM{G0azb|J43!q*CH2?u0XeiBMXm0=nj8n)Z@z1h(Ocw
zge3Ps@P*i9dnv>5;2q55+TlA*En$*3F`*j#ybS2%Vk0YyHtIQ6<G+0jB~hCx`h<S}
zIv7Bf>OuG)bZrEd1tRS2K|3VilPqL=r)~>^w@erXBpI3+cnV{jiCK7jW1cwX{XR}Y
zrr&Ry|32%rZxkip`m?DLE2`AyRd)T01tYJ&nX*61yY328_T~x|pH1+i*jUvzO8zCx
z_W4~>56Vm!)H4?z;>V!KTF<}Ak<OZ!lK7L~o_2_Fd?!`wdq<yva9k8m_*;ica$TW`
z45tmGayag6*Cz<<plkCz%=>y)Zkw@0EUA{do-P!7XPkj68I(qYd?qV>%$ghbH`;O@
z*b=%PnSxb6y-D|oMW;Oa_ZyX6!|Thsa&6)OfEQ)Q<={oxH3F$x{D#qWO6D?Oq+y){
z?G+zpp{B1%D&SkGS2HqPudw;!paU7zDz)A9w;rjCM*sS;T&!s5HrZ1$t{InXUQ<B*
zAt~$;tNnSWGSB1&61-g4DO69#sGY<BE>Nhi2{QytJfh=W@~72KJqS(Q=0l<yUg6yR
zUU(rhX}#;?a~v_(;H3vd)7dR?4Mh>{@T12Ka%5uUq*ayJJ@?}#m0Yuna;nr`4t`}?
z6mO~09^B4$T6j5eKbyCO;pcf(V%O8rQV!wsgjFP<6gfq+X$1|J$)-7qSU=T9<mTJ5
z^@$nyM|khx8YP&g%sM;5HfrIph-X&nI{n#~Ca~;lCpr(j(o8V5rbEdcAgb`eJ;n&>
zAPt2-3z%>1(x`Onu6p`W5z*|0y<<O0`s&}8FVFS}AwO=nAk_l3naIA2&`K6ydgbKu
zB$#OHKK%HZgeow+{c*b<8*ogvm@;~~5P#}5n&r5$I~ag=lk2mw=6vHFg}oz;UKjCM
zlQ{>D@2Ok~9R<V68eV+V&3=(X(>q7c4gki@$Czgi+X(kl(Z|aK5N|iiMHaXeuV6-0
zL7X}mY#zZJ3UeuaoQau%8@1w0Ut~M-h;3N;m~Fo)p<N%Z>_q03et4FBebo`TD}cFd
zjYK{nJ5hr^l8vpm<<wnFZnkz8#M+&xyFF@s4=@ya$<*2FVIB;`pjq*VT~Te07e4qK
ze57xTULE+8^+v9t*`B1hHkc#~Dj-<&q?-buvtE;+vzaiN$o>`O+Y%5fj`WKJV6-gr
zmpm0WymdA)n3U=T<?i|LG%YBuEAZ~fwWsj5Ck_4aZ;3kmW(jJNN;l36r7x|i1JQku
z&&7V>|Megi#4NiewBdo`YIk-i91B75mc9@qBU@TsE@}K0oc!LkZ-lq6k`!ijS`2u{
z-X*^HUn|X~Q1caCJOCGQhSSL_3E+#IA?+YF{$i#)z$$lA1)!EMhRGv#_<U9$`BFqp
zn&{&UtG}ppUF-EmB@Dcwxx>^IKdA}UeiOpM0!lwQ=6rLM2-$dz1u$xV=tRe>awqM?
z{9qC&EH#ZV5Wf;L_E&1^bD`<PFbTSfyphACv(&aV5lONpAi@JBmthOuFOi|c`)4)g
z>r+vma;F})7eQ<#ICK_(m#is4bRMaj^^FQ<m-?KzdC^&H&MvSm?R{d;*<8mgsC#A+
zZbz^~0J0KBZ5sn<t|?`#V@+bdd}@3VD+c_CXle|=CP3lSxPQFzCGCr+u{M32%YV)A
ziHPQi&~>)LrT0E|t-e_cu*7Be8C!)#mS*1!H7+<M2VRU*@rU7Vuzo&K4{@eW=7nnX
zV`Eb%z*)+(H|S?;(6b<dkO$G{d-532u-zK8o9;RvG72iK)n5Yr`!57fAY-%^*)M8B
z4OJZK&}lhxq_fj-L(@jY<+W;!w3N>5%d~{wp8Mt!YCh_%^vltFjm!P<NoaPc=Jt|u
zC(=#DFBD2P9W)OI4R0pG8ltoP8`|Ud8;Qq=Z>K5O#I|aAj)BKpwoj;Bt7q9Qj5_`i
zN^U3BM(422@JrrslQP_!HfD~Of04(3NbR)H-f|FXLNZo1PQkmAGjZDre8*JF%U+lI
z5X`A2oUAs0iBG@LMssDS9*0aG#Uh}&>Y1kfAgVdRG{-jnK!ga^gr{<iNfd==7S_x$
zjvUoVRg0f)Pf$U1MmqbjT~+m*Q0NKh_08&G0L=L9@*_aa)d>D$^0l?XXWnX4ZUj}%
z$HnY_<~;R+9NmrWt_4z-mEAON(rdKxkKHk70D=j<%ng^&i^Rc965kYfod`4weWUs-
z;Z5Xc>TCMDX;T@)JnW4sXMdV-h|C3}Pmj3^72+FhEE+I;w)vP;<qd6u3^NhvEin*J
zn9oiLP+qjLPRS0dz%5Xu?A`<K9DTcY3C-4nAvGPF=qF&~)x$YAd@p%`sQx!W^iv_K
zQwexc6~NKu<=tB_QI`iwH81(oc3{dc90+PbJa4c#8N4gNcGZy-M$qXonLSzu2x+vx
zHEeNzp4_;SH<hHJH%(DZ(nr&jq2J&%VD<HTrw5G&!TaCDZp3}v(-;^ROUB|}0EUew
z4rm-@XCBq(3GNfSZdX)y_i3!82Kr*6MLJ58xGt|?cIf;)7Ut;6_^&lH6hhbEHldbu
z02RIwe$o?fZEx@Bn-{S{WIw^A!e}!=K`Qt|+YWhth{l?io<wnNhU;RBJMzl&BJW0;
zcr_L5q3bPuw|bK6t5r4kZuCs35LW6~tKYx)LO*=7w96d)(Lsg{7zF@=4=}>85vstw
zU?`As?0I4BbI0)wM_tS(eJjj<Zg={{@pB-H8JQRjp`f-8tU{H}f~HEYTlE}0DVQ0S
z!NalCl#T~jVaB)OWRSzDhpF{IIwe3Zj+}@e<$$w=@WCLezrS6j<D%Gy6cd>7F%thi
zajqclJkP#`@{)Pe062!3h8V$439@g`EZAF)Isuxpdp?LCN&MX8gE&t?>Q9@G)VRvW
z-XXV_{Ua{WuHm0(*iFn$7h(YHdh-h@F~=8c*XKU{J;4iijBryP#BmD&Ag3{*6;DNc
z62ECg&uUj3SQJ7>ltaU2A9Rd$*YQ|(JsvWP6NsH7bIKs*w7&f_ospv)X~@5w4Iyqh
z(*8;2u_RUo4Q7n!D`?|AsV|4S8vJ+$8nm4^yFSU<#tY)mp#fi?bx_eyQB{`l0aKX3
zde!u3hlPaDZ1XTnxknALJ13v%r{?aDs2zBIHNfqU?~H<pRj~7xLjKL_;f~qO-PjlM
zPQ+&zkJ3|#l4k$AZrh)U02S(K>JJvNrUlaU@KW*aoWPG5d|Ds1=T(6lP@&yKf`49%
zHK;DnVoxG>@Os(ZXDS4{nBU$XzO~P$s0I0vg#-w=s=Lw4lOS#v(Fc=D?8Se9pp<Qd
zX`A0F^V@N0RsuMwB#)4{0f-drq)DbBUhvQe7>$cw?rnAyodJX0DnF2~bE7z(w;yLF
z2$Fjp&-z6A&ub<8wSTCrVYF!l9roKzQmV;a{Fq{eL}+F4&uWAc>amj9JiWOL-Hz9m
zInKJ$JhJCQ2o1c7Ctv)1%N^m_fWOIlQ`Y9f)iQBDIVlJ#GB!#Ava<$hbrql?iuuA0
z5-=iw*Bs1oJ&CQ(3k(|&3k2bYbXm~k;n_vD!%EZ5<5^@Q1b+RSR-o9HgRj<UqnRJ2
zqkwh;KJ32SM4%ycU@YeF^G}V_(a93(CwJcOi(a2^gS>rC{SCRnOr-DuDnK9~njRn4
zka#|1Sm8}bjkC{NY6|3T*iU?ykbnI2y2Wa%Y23vTv1u6O`}3C>6w0E>-T=0Ket^s;
zz+K%jEbx8%o!ec%v#pJH9{ZHxnLekCkuPvV#qwx23*5{NW+>{`Q;iCFT_q)I_7z+9
zYBj#ixuopYLd5Rs)Ni8KyO(*g-B>EkNY4}r@-#XaqM7xw)xP2K?ufKpyO#i14XNS+
z^0_>GbUj>&-I%zBu$SKHfO}1wpYUmdEYP_Y5ycp<0dwi!%S((%K~@;R86tY-o1iU>
z4ejz*MLlUeWohtya2W<mmsvtbQ7B?g-W0pqzjWz$(0^W7hvDBy%Bh|jO|R}p0YO?>
ziB*t*?w!^W^G#i482In1EBC)UoBI+GW34wk|Ea{lvZt1d21qp?yjQN<iY%(#i;m;|
zjca&T_f+kICm~?FdO#Rbwo<MM8`}g-^>q2nUvAc=c3MOwu--_a<iGTdns5L8RcN4!
z48t^pOx8AopXQAK9ITE?s#x8ok8h;NOau_QuB#)H@4_I&^(gJEPu8R3HC~VTn>BwX
zzp>raCgH(JGN3E7rsdR{k38C3Xj`fSV0)CCMN9y5Q#8@h{|dRzuBM-0{Yyv)ok&nx
zfKa4&kq!w(K%|3;pb(l;1*A$1z5J0T(mRL<Qlv|7A}Cd*NDW=2D!nAR-1`OY%iXhk
z=Ire3?Cj1nkFQQYSsfuZ=}UV8>-h!i>nrh{E?$|x+5&Q6#D`sz%84;<lTxSDjszLp
zBE#<=xv-rG;H~%WrEfPU$64O5Vob_+b0IeKh|p2+g7<e{;q4>g5y(GEP>O8q9XZ3t
zWEj2fzMKeR!2MFB+%6S|By+Tle^CO(vnup|w5T&#OOK&wEa@&x_~dM<Rrq-)yzwRe
zOHqC2etl7nae*G*mU5wo<@LAgK+r3}{kS_M@L~|2O#Wkd5e9FyG|Co2mbiN=Je299
zdxr&BV*(p$P!u3P+rI27i5L?MWHXJ5<CQKH@&us@ZzlJGSE?BZd%V$GW=gp|C-QzX
zY9A*K4LC3DFc+UWAe9OiHMAC-7G%LJ1&QLNw?M}`ie+AgIVvYM%`bOkmp<lxGdC<1
zs14tG5X`Ya{NQGq1Qe8|iBjTHti-b^wc7?rG)$R-c<?AQzT<Yejl8>iS)aW?tq|YO
zA;9yX_-6f5xYax2x26TCZ1s7X%R!TrxrprAp2Ys_CU~{oYaH~>t7Ny^ZO40QoJ413
z_TuC4rMLhM#qOdXyUTO~!&3w0TL04~8ca>pvAGPao-$-$`=W+GFF1mZN5mHRhpP$@
z!LewZr~e?Yww1Cn0$-v&BD+gE`X?UucQZ{ogufwJ49_%mEF=HXub+jTtbaN48Kfz?
zan4COYEBK5?Y}c6OcHN9iV%M|3M;_>r@#%-xWjBnY&P&S@#tqor$E*kq0dvfq}ZWY
zJs8$zgXce>2<!GJZm}&oL2;iZqv%zWe=W(wZ)`Tgq3xkUi^aQ3c5tw&YyQz8$9Cij
zy;5uOnBTAwiNg-oBAxXz{$)fcr%m8y4}JFs!RY(s#N<L90rQizfZ7P$Sr|sFIXUL8
zgGzs+CgZh&h)v@G`kceixhFP2*Lt=_ETHeOTVai%6Vp(%OU!qDkTm~yU^EPIHM1*G
z6jy(LKb_{1TWa}@R!|?=_a%1dm+lKB^xbefGqITni%gj3qj|iyNL$fC;ij<bdA$yF
zs6Piqh8HPm2b(Md`qP-`pc|3xx3h11ckp*<wX*5(l7g2vW$t4E>!h$OYwEZOWioVG
zJnGnbM!@G3$N0nYV%6BB?j5dEdf3WvtBLCJ!5q-B9x}d^{)$p1@KyWjU#lMc@7**=
zrWg(JaGDf;kQivSx%6$asZM5xm6{5)1wqkVPj@oMGVk(qd=Yrhe5eRcIB$a>>QLW&
zC!pj>sbsLigy{elqd>@*4R{hU%G*nPO)rzTv2o6W_3q05LKedgbevpv<PExaCv#q*
zO`j+{1u|u<pC%!_cD{~gSQOwSVj!Vz`lnA~#pRE$;LyNT<pEBQBPp;YwGADw3jt%z
z)ObF3sAb~*I6!=2=nM#YyS|1%RGLuRV#%-mXRbRT^>>rMmJl*FOP!6ju2ftwJFc6d
zxMP;lI{MN5d~WJxmgh)D`0D5AC*)TFtI8FGSe001stcbx`fY%pgYHEU_(rO52*3pP
z@`e;l+t2aTZa%_0mRUb53?*^xF;!ur$AoL<6A+tyX#R36Mt_I`uD5@2@;3=p8pE)e
zZTWIxvA}ZvNxL#)$)1|TQg!z2q87?yPYq_$#QRoMhfyb<X+W8Q>3g_Y30TTk^ie}{
z@hIi%h!}=SgTh1+I+m2z5W4r=V2pQajhJRkY$;s_1(h_l$^E5C<t^*oLtCf5`|i1c
z`@&0U-iuL3iX4pN`q0R3_CzAZNFK@H6D-Ti3{uYvDZnsG*M|Q5p)RQ}-~~30;o_a-
zE!l_p7y=NFd;Cg)JsDMSaVncnK*BmjJS4K-s_~^)=M7-uG4XcrL{Xy9plZ2y7B@{q
zkm533x1MtchsG_T6|yc7VGOjeAqOpr#-$uuak4!(-9|`-nNjpPb`5vTMwli$VWinv
zP&m#vi`{vMu7x4r(}{|ftpS2T=n9<@HOKU&qP7X4EV@f1tZPp@aPk_7!lYp?QSv%q
z6J^pUjH(vwY6#+`kT5-C6w)q=pw&=Aaq*>|{wjY1gBxEb6<mAs`n?xPwLxOwG`lkY
zat+a~=QH`<OEmGzBI%%Fqq;KLV%h(!hrU<c!tHKKxW?DSPmu1KS^7?^6FtApWX?ZA
zWCNUw;&}S8ykV`R_gt8``QMKzfP>s*8)x5n$}&wEZ&@u!FhAX1;pB`!A==TQU)qAU
zR(apdwt>faa<zBqlc!kd>}1GP@OX)(?+sOaI!EX4nr~q@*5(<2O~N@Un+`kUDR_8(
z&_SkjKp!^Ud2c|0f_lC|XJ+EnKYgSiEhZ`YP@+iTPXt_}P!VoJhiRf9np1h%<=!GG
z*Vy$oTxFto=5={JM}LQ5-R<b-T6VKgBGYfyunDEP@|Pf9vuoReN;BFY*N{|T8rKj@
zW4EE1zPMK~entnnC>0f5A@H&SNbyLv{!TKI#CmDlQF^#bEiS*zzW?ny>CLEB>Qh!f
z-}&PKU;I$7SY+(0_wyd$^*?jjOVLy0l!Er{GmaR$mb}wEH-&TUgA3t0vT|-93<BkS
zKoigUetE51(+6M<R%JtIH!*&fwG@RaH0H^kymJ3yi>Be04fHj6uA1cad5d$NGQ^Ce
zEVs4q>-Cue|9kYuWvt81z7%xCb(q2jkha~K)<Te_auP4dx^TVDRscwHd}+L=&VISA
zf?eyrQ+xR0>ACd|l(}wAmgf_e7>&<@Eml~T&xK*^$(pJz=-TjOvb_;`cWp-j=|iRi
z7|xn1sdPR`Iei(6Lo}VmMdBo*a!_k7KHn&r|E39CBxV8w0bxZw<cEb^XITOD>I7%d
z*rxYo=th_8R&{8@Y<iZI;yt*73wCth#QmZeedV6o?OmX_v5guU6O7GJvS-dRl2w0?
z(l8s92B#Hq)sp?1oH@`RW)#RxI~Lv8$;y#ROAx6Jp(Q$1rL&(|pDwpESyU(Ahg0b8
zO?p4<_1v%ow~zEm%7E-lP_HQ&wc*BQ0B>ba678>qVy6#Um^Egc|6d9-Wr^2i%!&}6
z%{7W!kX!5_^4ZUAXo*#oy``L-5}|Li-E`-L-ya<=kts&!MYM8Uuqe6hvh`0xk_aHj
zxOZk@@U2U-VGVOxeX;~(h(Euz9j&?%WufmA076GIS)u!pAdeb1$_>{v0Ysj6GK~`(
zM3`TD6T?n=)n|k0d5YEFPl>*vjqqKlJ$8~iO8O7X*_$C^al7Evuu0bFpvqUpO=X?0
zcBr0GIc*5J6PLPEA(t&b6!1(HuuX*C!ZecfGM$Za4;ng8Zyf#Ep9xt;$_0&VElp~5
z<c^sAn8ut=A9oMCkFKDjO*S4&%bdb?C#G~qk<E1<0UB3-W94UY)&FUGNAmSznh&ZU
z-zrGe#VFsRyzb9X3zFgOn-ny2yoQti^Y1^I^@^#CN~Ylewz<}&^qPRvL6?23e}4O7
z^~DXPjiiUr;%{F@V5kcJp#rFrhGBMc!OJ5_7t(bybQT$W5(d91uG=3y*stRo1pM`-
z-9%$j&c0}c3C80xLGrF75jK&XZgXV(PS($9{+Jb#&DuM4r+b-k-_jO{Kk?+vZoSp`
z)o?3GJ{3UP4EO2ni%lyPYS5!kZIj%hRfJ~@yjeHm`&c8%+YyFh4ZAG>9LSX;acg!>
zgR_*u-!VDD+v%Po*!KRXg!yi!?%YHIbK~|Srl#gAP)z*%AA`S-y6T>F4%J2Hj!*$N
zZ0e4|r8y#~&pxO-b<Rh?xCh+rCTr#h<L*XW24Hs?X|0Lcd$KLDLtlQkU;?JiRNP!s
z!5(tojEG4-Nbn2EK{Cp=eYGJ|yEETNJgV{fLF>M(y74NPGKu>`98KVDO)x{ccN-<e
zxAWrCTkz$UkS0fPAG>M|Ba5MpDDc|!YiHlCmSJyL&g~3ku(3|i!PCo$pPgG<87$&B
zo?~Uo2Wao=o?`*w(Fbs_Z1n|SjyqnSJu{g1(WHO^<iMVycDa+c4Hmm&fYZ6RFR;z@
z<>ED?+JaVVkuu20o%mT0m#~D?4G#Mo$T*g5JM)nJxMKfbZ<tlf9)taskoSpvW>=cB
z^HQj&Z1=5axf6HUQ2C|raza6lseZg#%_p2^20AtBRWBGW`C4NWD}`t<OLB~K;E8&4
z*847h8c;^bx85-n+2w6w#YehKf9V|eu`_p4=~iE}yuH^Lex!S`n!tyY-THj<tm_90
zrmfgj1l7xgQqHJ9eflP->@E09=RRGJ|6ecpm2TEt`A`QOizt4>LUj+G3SItyu@-i1
z*_y~aO6gsor1zf*m}X}@2V+~{*xBHf-RPxi3%8wVq(+}jV?zeFh>GUNdHuLr4Rs24
z{z3&Siu=y3LNowWfpc!7;5#+E$8tl{C`q*ynMr&XMdmyj@@DF=gY4?cSpb@p{)x&P
z@iBnqbwOzEu}`XH4sPU5pJ1-vbv*eXJe@|=Cz4X339ta!!BX1YL&;S>*W;8;wd*W&
zGdYmdpE4<Bzl^RiT-k?7^&wR^&D@3$a?*Kw>R_XTGR@^2dX=r}5reoW?`6XMTsEZ4
zI(F#Hyt*87JwbNg1EjNpr&+)^<3#!XncEuZ4272cfc@PxR~5&m@7R|cbKqoVMSP4U
zcB&bn?@L4D#(34?o~>Xfuf*uvh0mng{POaVhxwZ_o?i*c@cl;^eh5%<{4V8wP!<bZ
z@mjs$lEQ?Rm~M{)W(d6eDeRp8emQ@^pFR@@G+D<r@}CM67PO=`$Igc1>O=p@Q1QrC
z4w9hDOuG&w;AxMcU(nQEAe<xkABS1Z;$W@^Sf{e>RxMfOQyg~Wp981+hSlXv-{zFv
zukm!>d!9hr1{r+Ir{n>?{DA(I3x;3zX=P?e!%64&Z=<V<C;Ps=zC|OdJ)bpY92UsM
zNaGfhPv+%8h8iA*$Cmf&fXDWWT9lZ$bk6MJuDgQ;H-X}W(k(D%iQsg^>Ex(dc1($J
z4*7v>47p|t{P$$k-`huYdXKUB@>59p>c^Wi5B?cV=Z2oeLA~8nMlbIPIlLVB_~;I^
z{+wo$m$8KtGn`hl3laW35XfRF;Fqs|efDqzI#Iz+p2R<y2)$(PssR1CDl=x5DCc%c
zpcN8js~L|q83;(b8H;ISZ%(^`G`RjiHU1Mrn3LI51;XhA-b7%S9e(>lBaL-iW`$^E
zk|eNqQy*|5c1Q0R&v_T?=&3f8aHt^0bg6XgSe-`H4nod!Z7r=d^hjG1%fTZ;W+ja2
z=(QB4z{92)4vpIa4E;#jg<-avY$oJMZ{v>)Q8B}+Z<TQ1A~~(qf`d19M_=pGo_BzP
zJN~^;bRTe15#EX*8;yJ@BI1^{PhhK#Mn1yy1f{Cd9fCkJ+i2nq5s0?`mN+-g_+F^O
zG8sM`W2$9E<C%)U=?*@%1~N8jB_^+)UA_01f@?Ib($lTR4z?y9^6GFs<G|$!DS7_0
zb|;3>r}{k3_N@+eei-}!TL_gw51s*K4Wzeznkb=lkPt1VSe1*Jj_U5Zb1D;L8>0??
zBv{b^()ogl<N~~G%AdK7YBc-(UF*KuEH~O#vi%>|Ih`lT9R42Xh@NCk{m7)KRz5d*
z+d$39!H(l39TiJRDNI{_QLdL{>garJx*&JSL`QM6L2epPms?}2IB7?_<7DAiIslW>
zeRcV4#hx0?D1r0$_I=WMexT}Gz|A_*yt)v?<d?Ph46v`Xs%-1A1)OQE?mMk;r%s^F
zMVY^o7g)DU;nD#z=azeL1=`l1*C-mk=B8VI?DSuD$)mi%W7+~1l81;kD(K!N%Kt6!
zT#5)Ec|Sh2cC;ZX+w)yiwq)k#qhFki(}WF(C+w>^sr4`U=y9j2EpO`PtdM!~yUDXV
zP;@dv;*i3<8a3D<&3>xD5gT_z<5mwoKOP*IK3#pLCr=}0b{fhWG~ak}5!6cZq}igV
zOmeZ>%5TCG)_xHJCjEU#*RRXptIS2v>h^ui(qfi2zsmjBCiXC!{*!k!@;N;wUVWXH
zH(m&1Pe?9jolvyNiGP1kM|;S)5y>cTevf_BfaBZ&OY&vx6<smMvcHHc;t2$MT$WOX
zY3lFa>k^mAj$v-^;bmrMP}T8A8hhNr48*r!mtbV%hSg%T1ZNda2>^lcvC}>|&+7DQ
z4H?ZE63zBEyaPgB^P8kbwOF+l54=D*ia}&lu?X<1F#MF8{>)pG-s^)_%Y;<vyF8-L
zW{A5|l5!r$FY|V+W(jX<E@T(SjxQiSqz?=`L_Jx*M$*wodYvfEmO?dXsCdPTuXD4h
zgh6F^J$*tXZsC^5eG2IpxO{3Lnh^hdke?ylQ!jSX<ys!{Ug~C9Ef80cFP9bjeY#V{
zOuF`h;1}Y0^00fi^ZC*B507-|m?>kZw~1%=GX!V+)laDr=2zSc*<0YjubM|M!F@7K
zVb^Ip2a#Q?lA*lPY9PFnDt_G_{3?D=!10pfxUMjn?PxW^W0bE;a5qBdgRs!usl56}
z-{l{|_t1?ACl7mfPqv+#(7BfP%F{t*jwe=@<?|%l!CixE`l(YI+6V!=7a$v|Y_&VT
zkc=~Z3?DzBzjO1J7vNO(WR~YO)$xh725&#O{i<;YiG{k4U7!O9i!1IFg=%yuy5f@x
zf{fsVG-y;>sZ+)?KIVXYg$1i?tszGnVDh9)ll&#FR%|!yUgHIt`s!eg?9~bNT}*t(
zn<6k+xav#8K5&e1kAUd3^?L31$MxcUD-vXAi5msK&2piu_5kv-eQ7v<O6k2|L)PdY
z4}YbdSs3j$CH)L^+nOD0$ipb$1s%B$!pZ=&+r(cRlfSnb=R1!y{jghZ%3O;BKZ|+e
zo2h2-0qCIY|22vquW<T_E>=1YTDl=(_GI%C4>P0heT)nb+O8SrR4Hhi74Y|akyYw7
zDiE*0(eJ@qPZP$pyE1>S9#7}YxvkbOx1<?&Y=8h%__Md?OCcMBu5^;yf9-nu^4?2W
ztL6KiIGj4kI{Lur6k`-XvY~SbEzp=0vxbKz^Xo_@MUSsaew#%Kqn)$Pvt9npu7oD*
z7keF4PhEm>cITo2U9*lb-7Jgp`A+Xqp8eL_R^hR)g6hH9sbjYtqbff?mUNI$-b~@Y
z&!}nMah6srx#ku&qo)BOH@~f$@+Y*gP?dg(hhs7-um#?}Ru9h(kp5$UEk&}56eM%i
zHus7b5rRV3-E{IC)x&p7^P)Tp*eF0>>ZbUhudUhnvz}>k-J<-D75Q%SF3lH3uH!y)
zB|)|qjIF@SaQJFvuhQmk$%OxIgv?#cb+Cp$dCap5pF5kTw<dL{r_he<*bE=&m00u*
zFS5yjEL-rTR3Bx+N{i$0l(my>2y_5hYKP>3Y~P>yqhUt{gU(eg|2B!xLov^-zFyIs
zDgL_wO>9}>Ex<ogE-dowIsy!M6x*YHa3sdX$NL{Ql$*uN3Nhc2VUOW<S|BN1T%I9t
z1*0k_EzNSWJdyD*8VxPxDaI%GTiHZ(ag8$WPva2U;ted?61N8~CMe&VL7u7{O~giq
zBmRqM#%XWy9bWP*;2q=TZ-ZOg(p+2F`S7M0@*X-AbT(M+oF`P<cPFxl|I~vo^mCrf
zc+8)idV~Cqcd}jUk?#y=g~o-!J1<KDImPN9bBl_jFB4Mhckw-aZ~Nr;`oVmGL+q|p
zpE+cM4XD(gs#HZOSMJ$<Bh7zdeYrUJ#ZmxxyiS3n^HBJz3k<D6>ivEh+5&TsjPp}c
z!iS7cHGeOYt(nNrVb%tFVxwN0k$2l)7dDN<l$BLJyYWgK>jC-f%|><MPwga6V?!?_
zWVT-ig9?9P9O`detdw*1?o<T#xCrR3({M|GmVuZ$N=&X1Zh$$u_<>mMhA@HV(E$Q>
zbmQ5QV&UQCZ@J|8{0#MekJ<#C{s5}{L5up?Oa7$w8g8k}*~hQ7M!kD4{5@*H6w6D(
zRjxM;d<7^trcW>M>kP5^oBwJuh>!X<On5Oa7^|Y>*mmyo;F9QHSu<JLVgnEi!~r%m
zRlGbv4cb%OZ@UO+3wdrTt?_)7#Xu)yzKmq$CBh@2pg`5j6F!D+gB>64QAw=Z4wG~_
z0}8o0uuThw%yQs_TPzrJIt(ub>(cNuFoN@u)c!OVzjWHD90SvlA{kE6w`(AVnt(Vj
ztd_jSs!!(6O6v}WpG2_DIjT|fbh+<u#jDOv2gV4@uqFIi=}*$)vjHThY=;znYQBBC
zVPgsbU>*mGa&f*4x2-gLyh={I<M*yYM01JYsReo?_Y5b5x8%2OQDdy0r)Qxm?<F1i
zbn`k?VlmNqP=gI|;Pi>hQ6e$4UPzvs`~~@gsyA1@^Mo?OD|dkVl3@%{rgl?`Qd^NT
z$FW%#qajlCGM|mAd>kK;kPz?3H$*{`K-1M_XaXG4)A@n1kj5(Hqg`8Z)BYfu^aN<D
zO<#NJ3w%KJFVAnW)%nualahXN<6_Jl9AV0@=JSFU_8}NIER}S3BG>*WI9#S}T1aVb
zj*j&j=sjSRuVe?1OIoubMY4obZ&48lM<+jSixgD_ee#*YS2{aZzR5IA3qAL6+8?n>
z5%uqaEMbal4gMXz9^ue_$|R%+XSHN_gpA`meY=O1Lk%8Iwq_-bM>5CkRbNPQe|mqW
zV5Uz;x!v2z0}eS1IJl73`*Y2gSyNLBeB+9fb(MgO8vYhFIY%N8ExvX=S2u)|y+o*b
zip5J=^zLm-$SM8aZM(2&4e=ejVoZZ^q61GqKzm_&GrsP%;d+&`UYGJ&54`*Q@0pIj
z6Vb|=jgq&B;bF!0iL88)xk+vWdNK3u?TxYboN?>ETC<X?=X5u#7`2)y;AgR!ZrUF>
zB0ltJBdB;e!|_#2oHxmS{ffmbpCkaH!AgUJ>WsDA{j7oHctr@|BJjaa($9gsVS0Mk
zz`)J1tXK53=O*`kG*82MVOUd7;$188hkONM6mt8~J@oUvzqRm@hjcEVd@a5R+@=4I
zyTp`Xvcl5f;!cl2y0sf`U#{E6-oNLw?Xz@yjf#EC*ciPh@RGq1Qv?n&j7A0zaF9Q@
zal!fuF!DLb#PSHtrv%VkaSX07?0;YMmviH7qm2Y(eJP0Sg{Wy3n-?)3LGLkTNdVq>
zV7w%$mxJ@Ev7@oymOV{@76Q0EwspVSCQh~|FR_8R-^kxLx4Zu=BxYCusST#Cp$5>m
z1ct~{c}-Gnl|G#6XPs!Rca<ca8(_gGD$b%iz|Won%cGPAwB+_DT|k4+4_&s@srm{O
zPqlaF+T=kNkOS2o!e;!s*~&GD_zk+nYxI9C*3AG)0udC&avYW6&J1dhs<B64oGku0
z&E(JWg%7RojZ1ejrhm91y?#^aC;w_=tpoY{@*VXHUI3MdNXi5?GHJMN*Mzf90OBAt
z?PUX|>>=%`7gqr__z9}{Mx~nsZYT;RsD@#C$VyVCa(ah)Z*NvfxLW6=89>pso*VLb
zN5z>AQ<a95&jgr&s?YtS>KD$ThSmP|O&q+`!UZ&A@50c-u%u|pB<QMlk3svN33(X|
zOHVgkK(qn6A+BppcAnFt#6dJiUFp5DF0`$)3C+y=4pl>|P!Vcb?eG0S!jRSS;Dg!(
z?woC7A8|G6=uf>}!Q_U=?UtkNqw<ICEuE}Kf>*@ePM|Bf6BRdr|Ly$$8qU>^Na$1M
W$LeQ*CG?8F9JqT&U!zJ58}>hb)jSsf

literal 0
HcmV?d00001

diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.xml b/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.xml
new file mode 100644
index 0000000000..0c26c32e34
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/apps/emotion_reaction/emotion_reaction.xml
@@ -0,0 +1,4 @@
+<launch>
+  <include file="$(find jsk_unitree_startup)/launch/emotion_reaction.launch" >
+  </include>
+</launch>
diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/unitree_apps.installed b/jsk_unitree_robot/jsk_unitree_startup/apps/unitree_apps.installed
index 6bafcd68ef..eb2d4caf45 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/apps/unitree_apps.installed
+++ b/jsk_unitree_robot/jsk_unitree_startup/apps/unitree_apps.installed
@@ -3,3 +3,5 @@ apps:
     display: go1 watch dog
   - app: jsk_unitree_startup/lead_teleop
     display: go1 lead teleop
+  - app: jsk_unitree_startup/emotion_reaction
+    display: go1 emotion reaction
diff --git a/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh b/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh
index 4f508dca41..63a7f350d1 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh
+++ b/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh
@@ -30,6 +30,7 @@ if [ "$ROS_IP" == "192.168.123.14" ];then
     while ! eval rostopic info /robotsound 2$toStartlog; do sleep 2; done
     sleep 2 # wait for a while...
     roslaunch jsk_unitree_startup unitree_bringup.launch network:=ethernet &
+    roslaunch jsk_unitree_startup google_chat_ros.launch &
 fi
 
 eval echo "[jsk_startup] done... " $toStartlog
diff --git a/jsk_unitree_robot/jsk_unitree_startup/launch/emotion_reaction.launch b/jsk_unitree_robot/jsk_unitree_startup/launch/emotion_reaction.launch
new file mode 100644
index 0000000000..94515aaf26
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/launch/emotion_reaction.launch
@@ -0,0 +1,8 @@
+<launch>
+
+  <node name="emotion_talker"
+        pkg="jsk_unitree_startup" type="emotion_talker.py" />
+  <node name="emotion_subscriber"
+        pkg="jsk_unitree_startup" type="emotion_subscriber.l" />
+
+</launch>
diff --git a/jsk_unitree_robot/jsk_unitree_startup/launch/google_chat_ros.launch b/jsk_unitree_robot/jsk_unitree_startup/launch/google_chat_ros.launch
new file mode 100644
index 0000000000..d858a003f5
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/launch/google_chat_ros.launch
@@ -0,0 +1,22 @@
+<launch>
+  <arg name="google_chat_credentials_json" default="/var/lib/robot/dialogflow/sparky-pdse-c8cd9692a84f.json" />
+  <arg name="dialogflow_credentials_json" default="/var/lib/robot/dialogflow/facialexpression-rpwe-01533d0109c5.json" />
+
+  <!-- Google Chat ROS -->
+  <include file="$(find google_chat_ros)/launch/google_chat.launch">
+    <arg name="receiving_mode" value="pubsub" />
+    <arg name="project_id" value="sparky-pdse" />
+    <arg name="subscription_id" value="chat-sub" />
+    <arg name="respawn" value="true" />
+    <arg name="google_cloud_credentials_json" value="$(arg google_chat_credentials_json)"/>
+    <arg name="to_dialogflow_client" value="true" />
+  </include>
+
+  <!-- Dialogflow Client ROS -->
+  <include file="$(find dialogflow_task_executive)/launch/dialogflow_ros.launch">
+    <arg name="credential" value="$(arg dialogflow_credentials_json)" />
+    <arg name="project_id" value="facialexpression-rpwe" />
+    <arg name="enable_hotword" value="false" />
+  </include>
+
+</launch>
diff --git a/jsk_unitree_robot/jsk_unitree_startup/launch/unitree_bringup.launch b/jsk_unitree_robot/jsk_unitree_startup/launch/unitree_bringup.launch
index 7d06554a4d..4557b8eaee 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/launch/unitree_bringup.launch
+++ b/jsk_unitree_robot/jsk_unitree_startup/launch/unitree_bringup.launch
@@ -39,6 +39,12 @@
         args="call --wait /robot/start_app 'name: jsk_unitree_startup/lead_teleop'"
         output="screen" />
 
+  <!-- start emotion_reaction.launch -->
+  <node name="rosservice"
+        pkg="rosservice" type="rosservice"
+        args="call --wait /robot/start_app 'name: jsk_unitree_startup/emotion_reaction'"
+        output="screen" />
+
   <!-- let people to know unitree is bringup -->
   <node pkg="jsk_unitree_startup" type="wakeup.l"
         name="wakeup" output="log" />
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/emotion_subscriber.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/emotion_subscriber.l
new file mode 100755
index 0000000000..80745c6254
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/emotion_subscriber.l
@@ -0,0 +1,48 @@
+#!/usr/bin/env roseus
+
+(ros::load-ros-manifest "roseus")
+
+(ros::roseus "emotion-lister")
+(load "package://unitreeeus/unitree-interface.l")
+
+(require "package://jsk_unitree_startup/scripts/motions/happy.l")
+(require "package://jsk_unitree_startup/scripts/motions/joy.l")
+(require "package://jsk_unitree_startup/scripts/motions/affirmation.l")
+(require "package://jsk_unitree_startup/scripts/motions/negation.l")
+(require "package://jsk_unitree_startup/scripts/motions/love.l")
+(require "package://jsk_unitree_startup/scripts/motions/scared.l")
+(require "package://jsk_unitree_startup/scripts/motions/curious.l")
+(require "package://jsk_unitree_startup/scripts/motions/astonished.l")
+
+
+(defun emotion-cb(msg)
+  (let ((emotion (send msg :data)))
+    (ros::ros-info "Callback chatting-cb called with ~A" emotion)
+    (cond ((string= emotion "happy")
+	   (happy-main))
+	  ((string=  emotion "joy")
+	   (joy-main))
+	  ((string= emotion "affirmation")
+	   (affirmation-main))
+	  ((string= emotion "negation")
+	   (negation-main))
+	  ((string= emotion "love")
+	   (love-main))
+	  ((string= emotion "scared")
+	   (scared-main))
+	  ((string= emotion "curious")
+	   (curious-main))
+	  ((string= emotion "astonished")
+	   (astonished-main))
+	  (t
+	   (ros::ros-warn "called unknown emotion ~A" emotion)))
+    emotion))
+
+(defun main()
+  (go1-init)
+  (ros::subscribe "/emotion" std_msgs::String #'emotion-cb)
+  (ros::rate 10)
+  (while (ros::ok)
+    (ros::spin-once)))
+
+(main)
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/emotion_talker.py b/jsk_unitree_robot/jsk_unitree_startup/scripts/emotion_talker.py
new file mode 100755
index 0000000000..73cc7b5422
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/emotion_talker.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import rospy
+from std_msgs.msg import String
+from speech_recognition_msgs.msg import SpeechRecognitionCandidates
+from jsk_recognition_msgs.msg import PeoplePoseArray
+from dialogflow_task_executive.msg import DialogResponse
+import time
+import message_filters
+
+from threading import Lock
+
+
+class testNode():
+    def __init__(self):
+        # Publisher
+        self.pub = rospy.Publisher('/emotion', String, queue_size=1)
+
+        # Subscriber
+        self.sub1 = rospy.Subscriber('/speech_to_text', SpeechRecognitionCandidates, self.speech_callback)
+        self.sub2 = rospy.Subscriber('/people_pose', PeoplePoseArray, callback=self.callback)
+        self.sub3 = rospy.Subscriber('/dialog_response', DialogResponse, callback=self.df_cb)
+        self.duration_time = rospy.Duration(30)
+        self.prev_pose_detected_time = rospy.Time.now() - self.duration_time
+
+        self.lock = Lock()
+
+        queue_size = 10
+        fps = 100.
+        delay = 1 / fps * 0.5
+
+    def callback(self, msg):
+        if (rospy.Time.now() - self.prev_pose_detected_time) < self.duration_time:
+            return
+        poses = msg.poses
+        if len(poses) >= 1:
+            item = poses[0].limb_names
+            scores = poses[0].scores
+            target_limbs = [
+                "left_eye", "nose", "right_eye", "right_ear",
+                "left_ear"]
+            if all([name in item for name in target_limbs]):
+                message = "happy"
+                rospy.loginfo("received {}, current emotion is {}".format(item, message))
+                with self.lock:
+                    self.publish(message)
+                    self.prev_pose_detected_time = rospy.Time.now()
+                    rospy.sleep(5.0)
+
+    def publish(self, data):
+        self.pub.publish(data)
+
+    def speech_callback(self, msg):
+        word = msg.transcript[0]
+        if word in ["こんにちは",
+                    "ヤッホー",
+                    "こんばんは",
+                    "おはよう",
+                    "おはようございます"]:
+            message = "happy"
+        elif word in ["可愛いね",
+                      "可愛い",
+                      "かわいいね",
+                      "かわいい"]:
+            message = "joy"
+        elif word in ["散歩に行こう",
+                      "散歩",
+                      "行こう",
+                      "いこう"]:
+            message = "affirmation"
+        elif word in ["今日は行けないよ",
+                      "いけないよ",
+                      "行けないよ"]:
+            message = "negation"
+        elif word in ["大好きだよ",
+                      "好き",
+                      "すき"]:
+            message = "love"
+        elif word in ["あっち行って",
+                      "さようなら"]:
+            message = "scared"
+        else:
+            message = word
+        rospy.loginfo("received {}, current emotion is {}".format(word, message))
+        with self.lock:
+            self.publish(message)
+            rospy.sleep(5.0)
+
+    def df_cb(self, data):
+        if data.action == "Happy" or data.action == "input.welcome":
+            self.publish("happy")
+        elif data.action == "Smirking" or data.action == "Squinting":
+            self.publish("joy")
+        elif data.action == "Love":
+            self.publish("love")
+        elif data.action == "Fearful" or data.action == "Cry":
+            self.publish("scared")
+        elif data.action == "Relived":
+            self.publish("affirmation")
+        elif data.action == "Boring" or data.action == "Unpleasant":
+            self.publish("negation")
+        elif data.action == "input.unknown":
+            self.publish("curious")
+        elif data.action == "Angry" or data.action == "Astonished":
+            self.publish("astonished")
+        else:
+            rospy.logwarn("Unknown emotion")
+
+if __name__ == '__main__':
+    rospy.init_node('speech_to_emotion')
+
+    time.sleep(3.0)
+    node = testNode()
+
+    while not rospy.is_shutdown():
+        rospy.sleep(0.1)
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/affirmation.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/affirmation.l
new file mode 100644
index 0000000000..ac20ffd07c
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/affirmation.l
@@ -0,0 +1,46 @@
+#!/usr/bin/env roseus                                                                               \
+
+(ros::load-ros-manifest "roseus")
+(ros::roseus "unitree-affirmation")
+;;(load "package://unitreeeus/unitree-interface.l")
+
+;;down
+(defun affirmation-pose-1(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose '(0 0.2 0))
+         ))
+;;up
+(defun affirmation-pose-2(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose '(0 -0.2 0))
+         ))
+
+(defun reset-pose(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *go1* :angle-vector #f(0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0))
+         (send *ri* :body-pose '(0 0 0))
+         ))
+
+(defun affirmation-main()
+  (print "affirmation")
+  ;;(go1-init)
+  (reset-pose 1000)
+  (affirmation-pose-1 800)
+  (unix:usleep(* 1000 400))
+  (affirmation-pose-2 800)
+  (unix:usleep(* 1000 400))
+  (affirmation-pose-1 800)
+  (unix:usleep(* 1000 400))
+  (affirmation-pose-2 800)
+  (unix:usleep(* 1000 600))
+
+  (reset-pose 1000)
+  (affirmation-pose-1 800)
+  (unix:usleep(* 1000 400))
+  (affirmation-pose-2 800)
+  (unix:usleep(* 1000 400))
+  (affirmation-pose-1 800)
+  (unix:usleep(* 1000 400))
+  (affirmation-pose-2 800)
+  (unix:usleep(* 1000 600))
+  )
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/astonished.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/astonished.l
new file mode 100644
index 0000000000..c8d8ca80cb
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/astonished.l
@@ -0,0 +1,41 @@
+#!/usr/bin/env roseus
+
+(ros::load-ros-manifest "roseus")
+(ros::roseus "unitree-astonished")
+;;(load "package://unitreeeus/unitree-interface.l")
+
+(defun astonished-pose-1(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :body-pose (coords :pos #f(0 0 30)))
+	 (send *ri* :body-pose (coords :pos #f(0 0 30)))
+	 ))
+
+(defun astonished-pose-2(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :body-pose '(0 -0.4 0))
+	 (send *ri* :body-pose '(0 -0.4 0))
+	 ))
+
+(defun reset-pose(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :angle-vector #f(0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0))
+	 (send *ri* :body-pose '(0 0 0))
+	 ))
+
+(defun astonished-main()
+  ;;(print "astonished")
+  ;;(go1-init)
+  ;;(make-irtviewer)
+  ;;(send *irtviewer* :draw-objects)
+  ;;(objects (list *go1*))
+  (reset-pose 1000)
+  (astonished-pose-1 800)
+  (unix:usleep (* 1000 1000))
+  (reset-pose 800)
+  (unix:usleep (* 1000 400))
+  (astonished-pose-2 800)
+  (unix:usleep (* 1000 1000))
+  (reset-pose 800)
+  (unix:usleep (* 1000 800))
+
+  )
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/curious.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/curious.l
new file mode 100644
index 0000000000..bd76eff6a7
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/curious.l
@@ -0,0 +1,45 @@
+#!/usr/bin/env roseus
+(ros::load-ros-manifest "roseus")
+(ros::roseus "unitree-curious")
+(load "package://unitreeeus/unitree-interface.l")
+
+(defun curious-pose-1(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :body-pose '(0 -0.4 0))
+	 (send *ri* :body-pose '(0 -0.4 0))
+	 ))
+
+(defun curious-pose-2(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :body-pose '(0.4 -0.4 0))
+	 (send *ri* :body-pose '(0.4 -0.4 0))
+	 ))
+
+(defun curious-pose-3(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :body-pose '(-0.4 -0.4 0))
+	 (send *ri* :body-pose '(-0.4 -0.4 0))
+	 ))
+
+(defun reset-pose(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :angle-vector #f(0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0))
+	 (send *ri* :body-pose '(0 0 0))
+	 ))
+
+(defun curious-main()
+  (print "curious")
+  (go1-init)
+  ;;(make-irtviewer)
+  ;;(send *irtviewer* :draw-objects)
+  ;;(objects (list *go1*))
+  (reset-pose 1000)
+  (curious-pose-1 800)
+  (unix:usleep (* 1000 800))
+  (curious-pose-2 800)
+  (unix:usleep (* 1000 1500))
+  (curious-pose-3 800)
+  (unix:usleep (* 1000 1500))
+  (reset-pose 800)
+  (unix:usleep (* 1000 800))
+  )
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/happy.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/happy.l
new file mode 100644
index 0000000000..5dced3fdb2
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/happy.l
@@ -0,0 +1,48 @@
+#!/usr/bin/env roseus
+(ros::load-ros-manifest "roseus")
+(ros::roseus "unitree-happy")
+;;(load "package://unitreeeus/unitree-interface.l")
+
+(defun happy-pose-1(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :body-pose '(0.4 -0.4 -0.2))
+	 (send *ri* :body-pose '(0.4 -0.4 -0.2))
+	 ))
+
+(defun happy-pose-2(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :body-pose '(-0.4 -0.4 0.2))
+	 (send *ri* :body-pose '(-0.4 -0.4 0.2))
+	 ))
+
+(defun reset-pose(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+	 (send *go1* :angle-vector #f(0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0))
+	 (send *ri* :body-pose '(0 0 0))
+	 ))
+
+(defun happy-main()
+  (print "happy")
+  ;;(go1-init)
+  ;;(make-irtviewer)
+  ;;(send *irtviewer* :draw-objects)
+  ;;(objects (list *go1*))
+  (reset-pose 1000)
+  (happy-pose-1 800)
+  (unix:usleep (* 1000 1000))
+  (reset-pose 800)
+  (unix:usleep (* 1000 800))
+  (happy-pose-2 800)
+  (unix:usleep (* 1000 1000))
+  (reset-pose 800)
+  (unix:usleep (* 1000 800))
+
+  (happy-pose-1 800)
+  (unix:usleep (* 1000 1000))
+  (reset-pose 800)
+  (unix:usleep (* 1000 800))
+  (happy-pose-2 800)
+  (unix:usleep (* 1000 1000))
+  (reset-pose 800)
+  (unix:usleep (* 1000 800))
+  )
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/joy.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/joy.l
new file mode 100644
index 0000000000..240c01d001
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/joy.l
@@ -0,0 +1,51 @@
+#!/usr/bin/env roseus                                                                               1;5202;0c\
+
+(ros::load-ros-manifest "roseus")
+(ros::roseus "unitree-joy")
+;;(load "package://unitreeeus/unitree-interface.l")
+
+;;down
+(defun joy-pose-1(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose (coords :pos #f(0 0 -90)))
+         ))
+;;up
+(defun joy-pose-2(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose (coords :pos #f(0 0 30)))
+         ))
+
+(defun reset-pose(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *go1* :angle-vector #f(0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0))
+         (send *ri* :body-pose '(0 0 0))
+         ))
+
+(defun joy-main()
+  (print "joy")
+  ;;(go1-init)
+  (reset-pose 600)
+  (joy-pose-1 400)
+  (unix:usleep(* 1000 400))
+  (joy-pose-2 800)
+  (unix:usleep(* 1000 400))
+  (reset-pose 1000)
+  (unix:usleep(* 1000 400))
+  (joy-pose-1 800)
+  (unix:usleep(* 1000 400))
+  (joy-pose-2 800)
+  (unix:usleep(* 1000 600))
+
+  (reset-pose 1000)
+  (joy-pose-1 800)
+  (unix:usleep(* 1000 400))
+  (joy-pose-2 800)
+  (unix:usleep(* 1000 400))
+  (reset-pose)
+  (unix:usleep(* 1000 400))
+  (joy-pose-1 800)
+  (unix:usleep(* 1000 400))
+  (joy-pose-2 800)
+  (unix:usleep(* 1000 600))
+
+  )
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/love.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/love.l
new file mode 100644
index 0000000000..648af83202
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/love.l
@@ -0,0 +1,64 @@
+#!/usr/bin/env roseus                                                                               \
+
+(ros::load-ros-manifest "roseus")
+(ros::roseus "unitree-love")
+;;(load "package://unitreeeus/unitree-interface.l")
+
+
+(defun love-pose-1(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose '(0 0.4 -0.2))
+         ))
+
+(defun love-pose-2(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose '(0 0 -0.2))
+         ))
+
+(defun love-pose-3(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose '(0 0.4 0.2))
+         ))
+
+(defun love-pose-4(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose '(0 0 0.2))
+         ))
+
+(defun reset-pose(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *go1* :angle-vector #f(0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0))
+         (send *ri* :body-pose '(0 0 0))
+         ))
+
+(defun love-main()
+  (print "love")
+  ;;(go1-init)
+  (reset-pose 1000)
+  (unix:usleep(* 1000 600))
+  (love-pose-1 800)
+  (unix:usleep(* 1000 400))
+  (love-pose-2 800)
+  (unix:usleep(* 1000 400))
+  (reset-pose)
+  (unix:usleep(* 1000 600))
+  (love-pose-1 800)
+  (unix:usleep(* 1000 400))
+  (love-pose-2 800)
+  (unix:usleep(* 1000 400))
+  (reset-pose)
+  (unix:usleep(* 1000 800))
+
+  (love-pose-3 800)
+  (unix:usleep(* 1000 400))
+  (love-pose-4 800)
+  (unix:usleep(* 1000 400))
+  (reset-pose)
+  (unix:usleep(* 1000 600))
+  (love-pose-3 800)
+  (unix:usleep(* 1000 400))
+  (love-pose-4 800)
+  (unix:usleep(* 1000 400))
+  (reset-pose)
+  (unix:usleep(* 1000 800))
+  )
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/negation.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/negation.l
new file mode 100644
index 0000000000..88734a206e
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/negation.l
@@ -0,0 +1,61 @@
+#!/usr/bin/env roseus                                                                               \
+
+(ros::load-ros-manifest "roseus")
+(ros::roseus "unitree-negation")
+;;(load "package://unitreeeus/unitree-interface.l")
+
+;;down
+(defun negation-pose-1(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose '(0 0 -0.2))
+         ))
+;;up
+(defun negation-pose-2(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose '(0 0 0.2))
+         ))
+
+(defun reset-pose(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *go1* :angle-vector #f(0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0))
+         (send *ri* :body-pose '(0 0 0))
+         ))
+
+(defun negation-main()
+  (print "negation")
+  ;;(go1-init)
+  (reset-pose 1000)
+  (negation-pose-1 800)
+  (unix:usleep(* 1000 200))
+  (reset-pose)
+  (unix:usleep(* 1000 200))
+  (negation-pose-2 800)
+  (unix:usleep(* 1000 200))
+  (reset-pose)
+  (unix:usleep(* 1000 200))
+  (negation-pose-1 800)
+  (unix:usleep(* 1000 200))
+  (reset-pose)
+  (unix:usleep(* 1000 200))
+  (negation-pose-2 800)
+  (unix:usleep(* 1000 200))
+  (reset-pose)
+  (unix:usleep(* 1000 600))
+
+  (reset-pose 1000)
+  (negation-pose-1 800)
+  (unix:usleep(* 1000 200))
+  (reset-pose)
+  (unix:usleep(* 1000 200))
+  (negation-pose-2 800)
+  (unix:usleep(* 1000 200))
+  (reset-pose)
+  (unix:usleep(* 1000 200))
+  (negation-pose-1 800)
+  (unix:usleep(* 1000 200))
+  (reset-pose)
+  (unix:usleep(* 1000 200))
+  (negation-pose-2 800)
+  (reset-pose)
+  (unix:usleep(* 1000 600))
+  )
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/scared.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/scared.l
new file mode 100644
index 0000000000..3ee72bfdac
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/motions/scared.l
@@ -0,0 +1,34 @@
+#!/usr/bin/env roseus                                                                               \
+
+(ros::load-ros-manifest "roseus")
+(ros::roseus "unitree-scared")
+;;(load "package://unitreeeus/unitree-interface.l")
+
+
+(defun scared-pose-1(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose (coords :pos #f(0 0 -90)))
+         ))
+
+(defun scared-pose-2(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *ri* :body-pose '(0 0.3 -0.2))
+         ))
+
+(defun reset-pose(&optional (time 3000))
+  (progn (send *go1* :angle-vector (send *ri* :state :potentio-vector))
+         (send *go1* :angle-vector #f(0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0 0.0 45.0 -90.0))
+         (send *ri* :body-pose '(0 0 0))
+         ))
+
+(defun scared-main()
+  (print "scared")
+  ;;(go1-init)
+  (reset-pose 1000)
+  (unix:usleep(* 1000 1000))
+  (scared-pose-1 800)
+  (unix:usleep(* 1000 1000))
+  (scared-pose-2 800)
+  (unix:usleep(* 1000 2000))
+  (reset-pose)
+)

From 0231f70cb3b26166dee126961b7a2d5a12df99aa Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Fri, 5 Aug 2022 00:11:29 +0900
Subject: [PATCH 32/77] [jsk_unitree_startup/cross] Add y or n

---
 jsk_unitree_robot/cross/compress.sh | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/jsk_unitree_robot/cross/compress.sh b/jsk_unitree_robot/cross/compress.sh
index 57a097320e..fd8a79096b 100755
--- a/jsk_unitree_robot/cross/compress.sh
+++ b/jsk_unitree_robot/cross/compress.sh
@@ -2,12 +2,27 @@
 
 if [ -e "arm64v8_User" ]; then
     if [ -e "arm64v8_User.tar.gz" ]; then
+        echo "WARNING: Compressed arm64v8_User.tar.gz is found."
+        read -p "WARNING: Are you sure to continue [y/N] ? " -n 1 -r
+        echo    # (optional) move to a new line
+        if [[ $REPLY =~ ^[Yy]$ ]]; then
+            tar -zcvf arm64v8_User.tar.gz arm64v8_User
+        fi
+    else
         tar -zcvf arm64v8_User.tar.gz arm64v8_User
     fi
 fi
 
 if [ -e "arm64v8_System" ]; then
     if [ -e "arm64v8_System.tar.gz" ]; then
+        echo "WARNING: Compressed arm64v8_System.tar.gz is found."
+        read -p "WARNING: Are you sure to continue [y/N] ? " -n 1 -r
+        echo    # (optional) move to a new line
+        if [[ $REPLY =~ ^[Yy]$ ]]; then
+            chmod 644 arm64v8_System/ros1_inst/share/pr2eus/*.l
+            tar -zcvf arm64v8_System.tar.gz arm64v8_System
+        fi
+    else
         chmod 644 arm64v8_System/ros1_inst/share/pr2eus/*.l
         tar -zcvf arm64v8_System.tar.gz arm64v8_System
     fi

From f8e3778dbe0ae069009adc75ef77571720b73953 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Fri, 5 Aug 2022 15:52:54 +0900
Subject: [PATCH 33/77] [jsk_unitree_startup] Add imageai.sh which is running
 on default unitree pro

---
 .../jsk_unitree_startup/autostart/imageai.sh  | 72 +++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100755 jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh

diff --git a/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh b/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
new file mode 100755
index 0000000000..6401998441
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+Nano1="192.168.123.13"  ## SecNanoRight(1-2)
+Nano2="192.168.123.14"	## SecNanoLeft(3-4)
+Nano3="192.168.123.15"	## MasterNano(5)
+eval echo "[imageai] starting ... " $toStartlog
+
+mLRootPATH="/home/unitree/Unitree/autostart/imageai/"
+updatePackagePATH="/home/unitree/mLComSystemFrame.tar.gz"
+
+echo -e "\e[1;32m**** 1. Check if the program needs to be updated ? ****\e[0m"
+checkIFUpdate(){
+	if [ -f "$updatePackagePATH" ];then
+		echo -e "\e[1;32m	The update file exists, it will be updating soon ...\e[0m"
+		tar -zxvf $updatePackagePATH -C $mLRootPATH > /dev/null; sleep 1
+		rm -rf $updatePackagePATH
+		echo -e "\e[1;32m	Updating Success.\e[0m"
+	else
+		echo -e "\e[1;31m	NO Need to update!\e[0m"
+	fi
+}
+
+checkIFUpdate
+# dd=$?
+
+#declare -i lossNano1=-1
+#declare -i lossNano2=-1
+#declare -i lossNano3=-1
+
+#echo -e "\e[1;32m**** 2. Check if all Nano'IP Address is OK ? ****\e[0m"
+
+#until (( lossNano1 + lossNano2 + lossNano3 == 0 ))
+#do
+#	lossNano1=`ping -c 2 -w 2 $Nano1 | grep loss | awk '{print $6}' | awk -F "%" '{print $1}'`
+#	echo $lossNano1
+#
+#	lossNano2=`ping -c 2 -w 2 $Nano2 | grep loss | awk '{print $6}' | awk -F "%" '{print $1}'`
+#	echo $lossNano2
+#
+#	lossNano3=`ping -c 2 -w 2 $Nano3 | grep loss | awk '{print $6}' | awk -F "%" '{print $1}'`
+#	echo $lossNano3
+#	#sleep 10
+#done
+
+#echo "	IP is Right!"
+
+## GET PC's Address
+localIPAddr=`ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6| head -n 1 | awk '{print $2}'|tr -d "addr:"`
+echo "Local Address: "$localIPAddr
+
+echo -e "\e[1;32m**** 2. Start Main Application ... ****\e[0m"
+if [ $localIPAddr == $Nano3 ];then
+	echo "	MasterNano"
+	############### MasterNano doing things!!!!
+	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqMNConfig.yaml; exec bash"
+	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/pyScripts; python3 live_human_pose.py; exec bash"
+
+elif [ $localIPAddr == $Nano2 ];then
+	echo "	SecNanoLeft"
+	############### SecNanoLeft(3-4) doing things!!!!
+	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNLConfig.yaml; exec bash"
+	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNLConfig.yaml 1; exec bash"
+
+elif [ $localIPAddr == $Nano1 ];then
+	echo "	SecNanoRight"
+	############### SecNanoRight(1-2) doing things!!!!
+	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNRConfig.yaml; exec bash"
+	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNRConfig.yaml 1; exec bash"
+else
+	echo "	Not Found $localIPAddr in IP-Clump!"
+fi
+
+echo "	EveryThing is done!"

From 8d9eb4a462e34bd62732f70f49e5c2cf1d22f8bd Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Fri, 5 Aug 2022 15:54:34 +0900
Subject: [PATCH 34/77] [jsk_unitree_startup] Launch trt pose on jetson nano2gb
 (192.168.123.13)

---
 jsk_unitree_robot/cross/install.sh              | 14 +++++++++++---
 .../jsk_unitree_startup/autostart/imageai.sh    |  3 ++-
 .../scripts/publish_human_pose.diff             | 17 ++++++++++++++++-
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index e05fa2f36f..a2d184c6ee 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -119,6 +119,7 @@ function copy_data () {
 
 if [[ ${TYPE} == "Pro" ]] ; then
     copy_data pi 192.168.123.161
+    copy_data unitree 192.168.123.13
     copy_data unitree 192.168.123.14
     ## copy_data unitree 192.168.123.15 : Pro : No Space for auto start
 elif [[ ${TYPE} == "Air" ]] ; then
@@ -129,8 +130,10 @@ else
 fi
 
 if [[ "${TARGET_DIRECTORY}" == "User" ]]; then
+    cuda_ip="192.168.123.13"
     if [[ ${TYPE} == "Pro" ]] ; then
-        cuda_ip="192.168.123.15"
+        sshpass -p 123 scp ${TARGET_MACHINE}_${TARGET_DIRECTORY}/src/jsk_robot/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh unitree@192.168.123.13:/home/unitree/Unitree/autostart/imageai/imageai.sh
+        sshpass -p 123 scp ${TARGET_MACHINE}_${TARGET_DIRECTORY}/src/jsk_robot/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh unitree@192.168.123.15:/home/unitree/Unitree/autostart/imageai/imageai.sh
     elif [[ ${TYPE} == "Air" ]] ; then
         cuda_ip="192.168.123.13"
     fi
@@ -142,8 +145,13 @@ if [[ "${TARGET_DIRECTORY}" == "User" ]]; then
     sshpass -p 123 scp ${TARGET_MACHINE}_${TARGET_DIRECTORY}/src/jsk_robot/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff unitree@${cuda_ip}:/tmp/publish_human_pose.diff
     sshpass -p 123 ssh -t unitree@${cuda_ip} bash -c 'ls; OUT="$(patch -p0 --backup --forward /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/pyScripts/live_human_pose.py < /tmp/publish_human_pose.diff | tee /dev/tty)" || echo "${OUT}" | grep "Skipping patch" -q || (echo "$OUT" && false);'
 
-    if [[ ${TYPE} == "Air" ]] ; then
-        sshpass -p 123 ssh -t unitree@${cuda_ip} "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/pyScripts/live_human_pose.py"
+    # launch live_human_pose.py on jetson nano (192.168.123.13)
+    sshpass -p 123 ssh -t unitree@${cuda_ip} "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/pyScripts/live_human_pose.py"
+    # replace 192.168.123.15 -> 192.168.123.13 because live_human_pose.py is running on jetson nano (192.168.123.13)
+    if [[ ${TYPE} == "Pro" ]] ; then
+        sshpass -p 123 ssh -t unitree@192.168.123.13 "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/config/mqSNNRConfig.yaml"
+        sshpass -p 123 ssh -t unitree@192.168.123.14 "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/config/mqSNNLConfig.yaml"
+        sshpass -p 123 ssh -t unitree@192.168.123.15 "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/config/mqMNConfig.yaml"
     fi
 fi
 
diff --git a/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh b/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
index 6401998441..6f98fd581b 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
+++ b/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
@@ -52,7 +52,7 @@ if [ $localIPAddr == $Nano3 ];then
 	echo "	MasterNano"
 	############### MasterNano doing things!!!!
 	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqMNConfig.yaml; exec bash"
-	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/pyScripts; python3 live_human_pose.py; exec bash"
+	# gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/pyScripts; python3 live_human_pose.py; exec bash"
 
 elif [ $localIPAddr == $Nano2 ];then
 	echo "	SecNanoLeft"
@@ -65,6 +65,7 @@ elif [ $localIPAddr == $Nano1 ];then
 	############### SecNanoRight(1-2) doing things!!!!
 	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNRConfig.yaml; exec bash"
 	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNRConfig.yaml 1; exec bash"
+  gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/pyScripts; python3 live_human_pose.py; exec bash"
 else
 	echo "	Not Found $localIPAddr in IP-Clump!"
 fi
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff b/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff
index 960c221f2f..cfae1f90d7 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff
@@ -1,6 +1,12 @@
 --- live_human_pose.py	2022-05-26 00:17:04.634784206 +0900
 +++ live_human_pose_jsk.py	2022-05-26 00:17:18.102931810 +0900
-@@ -169,6 +169,8 @@
+@@ -1,4 +1,5 @@
+ #coding:utf-8
++import base64
+ import json
+ import trt_pose . coco
+ import trt_pose . models
+@@ -169,6 +171,8 @@
      if 39 - 39: o00ooo0 - II111iiii * OoO0O00 % o0oOOo0O0Ooo * II111iiii % II111iiii
      cv2 . circle ( src , ( i1I1iI , o0O ) , 8 , I1i1I1II , - 1 )
   iI1Ii11111iIi . write ( src )
@@ -9,3 +15,12 @@
  # cv2 . imshow ( "ai" , src )
  # cv2 . waitKey ( 1 )
   if 59 - 59: iIii1I11I1II1 + I1IiiI - o0oOOo0O0Ooo - I1IiiI + Oo / I1ii11iIi11i
+@@ -199,6 +203,8 @@
+  print ( "AI is working ...." , camIndex . value )
+  Oo0oOOo , Oo0OoO00oOO0o = o0OOO [ camIndex . value - 1 ] . read ( )
+  OOO00O = time . time ( )
++ # add by iory 2022.8.6
++ O0ii1ii1ii.publish("vision/front_camera", base64.b64encode(cv2.imencode('.jpg', Oo0OoO00oOO0o, [int(cv2.IMWRITE_JPEG_QUALITY), 90])[1]).decode('ascii'))
+  OOoOO0oo0ooO = cv2 . resize ( Oo0OoO00oOO0o , dsize = ( OooO0 , II11iiii1Ii ) , interpolation = cv2 . INTER_AREA )
+  iI ( OOoOO0oo0ooO , Oo0OoO00oOO0o , OOO00O )
+  if 98 - 98: I1II1 * I1II1 / I1II1 + O00ooOO

From 2b7943ce320d2332f338a2419c00ec1164470b23 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sat, 6 Aug 2022 01:47:38 +0900
Subject: [PATCH 35/77] [jsk_unitree_startup] Add camera image publisher

---
 .../autostart/jsk_startup.sh                  |  4 +
 .../launch/camera_image_publisher.launch      |  9 ++
 .../scripts/camera_image_publisher.py         | 86 +++++++++++++++++++
 3 files changed, 99 insertions(+)
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/launch/camera_image_publisher.launch
 create mode 100755 jsk_unitree_robot/jsk_unitree_startup/scripts/camera_image_publisher.py

diff --git a/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh b/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh
index 4f508dca41..0e96a8e217 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh
+++ b/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh
@@ -20,6 +20,10 @@ if [ "$ROS_IP" == "192.168.123.161" ];then
     roslaunch --screen respeaker_ros sample_respeaker.launch language:=ja-JP publish_tf:=false launch_soundplay:=false &
 fi
 
+if [ "$ROS_IP" == "192.168.123.13" ];then
+    roslaunch jsk_unitree_startup camera_image_publisher.launch &
+fi
+
 if [ "$ROS_IP" == "192.168.123.14" ];then
     # 192.168.123.14 is force updated within install.sh for Go1 Air
     if [ "$ROS_IP" == "192.168.123.13" ];then
diff --git a/jsk_unitree_robot/jsk_unitree_startup/launch/camera_image_publisher.launch b/jsk_unitree_robot/jsk_unitree_startup/launch/camera_image_publisher.launch
new file mode 100644
index 0000000000..942961102c
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/launch/camera_image_publisher.launch
@@ -0,0 +1,9 @@
+<launch>
+
+  <node name="front_camera"
+        pkg="jsk_unitree_startup" type="camera_image_publisher.py"
+        output="screen"
+        respawn="true" >
+  </node>
+
+</launch>
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/camera_image_publisher.py b/jsk_unitree_robot/jsk_unitree_startup/scripts/camera_image_publisher.py
new file mode 100755
index 0000000000..ca1d079204
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/camera_image_publisher.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+
+import base64
+
+import cv2
+import rospy
+import numpy as np
+from sensor_msgs.msg import Image
+from sensor_msgs.msg import CompressedImage
+import cv_bridge
+
+from paho.mqtt import client as mqtt_client
+
+
+def decode_image_cv2(b64encoded):
+    bin = b64encoded.split(",")[-1]
+    bin = base64.b64decode(bin)
+    bin = np.frombuffer(bin, np.uint8)
+    img = cv2.imdecode(bin, cv2.IMREAD_COLOR)
+    return img
+
+
+class ImagePublisher(object):
+    broker = '192.168.123.161'
+    port = 1883
+    topic = "vision/front_camera"
+
+    def __init__(self):
+        self.bridge = cv_bridge.CvBridge()
+        self.encoding = rospy.get_param('~encoding', 'bgr8')
+        self.frame_id = rospy.get_param('~frame_id', 'camera')
+        self.pub = rospy.Publisher('~output', Image, queue_size=1)
+        self.pub_compressed = rospy.Publisher(
+            '{}/compressed'.format(rospy.resolve_name('~output')),
+            CompressedImage, queue_size=1)
+
+        self.connect_mqtt()
+        self.subscribe()
+        self.client.loop_start()
+
+    def connect_mqtt(self):
+        def on_connect(client, userdata, flags, rc):
+            if rc == 0:
+                print("Connected to MQTT Broker! ({}:{})".format(self.broker, self.port))
+            else:
+                print("Failed to connect, return code %d\n", rc)
+        self.client = mqtt_client.Client(rospy.get_name())
+        self.client.on_connect = on_connect
+        self.client.connect(self.broker, self.port)
+        return
+
+    def subscribe(self):
+        def on_message(client, userdata, msg):
+            rospy.loginfo("Received `{}` topic".format(msg.topic))
+
+            if self.pub.get_num_connections() == 0 and self.pub_compressed.get_num_connections() == 0:
+                return
+            now = rospy.Time.now()
+            frame = decode_image_cv2(msg.payload.decode('ascii'))
+            if self.pub.get_num_connections() > 0:
+                img_msg = self.bridge.cv2_to_imgmsg(
+                    frame, encoding=self.encoding)
+                img_msg.header.frame_id = self.frame_id
+                img_msg.header.stamp = now
+                self.pub.publish(img_msg)
+            if self.pub_compressed.get_num_connections() > 0:
+                compressed_msg = CompressedImage()
+                # compressed format is separated by ';'.
+                # https://github.com/ros-perception/image_transport_plugins/blob/f0afd122ed9a66ff3362dc7937e6d465e3c3ccf7/compressed_image_transport/src/compressed_publisher.cpp#L116-L128
+                compressed_msg.format = '{}; {} compressed {}'.format(
+                    self.encoding, 'jpg', 'bgr8')
+                compressed_msg.data = np.array(
+                    cv2.imencode('.jpg', frame)[1]).tostring()
+                compressed_msg.header.frame_id = self.frame_id
+                compressed_msg.header.stamp = now
+                self.pub_compressed.publish(compressed_msg)
+
+        self.client.subscribe(self.topic)
+        self.client.on_message = on_message
+        return
+
+
+if __name__ == '__main__':
+    rospy.init_node('camera_image_publisher')
+    ImagePublisher()
+    rospy.spin()

From c9f5b1ab4d3ca634fa95a4d3db98b7ce3b161e59 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sun, 7 Aug 2022 19:19:41 +0900
Subject: [PATCH 36/77] [jsk_unitree_startup] Add walk_notifyer

---
 .../launch/walk_notifier.launch               |  34 ++++++
 .../scripts/location_node.py                  | 109 ++++++++++++++++++
 .../scripts/walk_notifier.py                  |  87 ++++++++++++++
 3 files changed, 230 insertions(+)
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/launch/walk_notifier.launch
 create mode 100755 jsk_unitree_robot/jsk_unitree_startup/scripts/location_node.py
 create mode 100755 jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py

diff --git a/jsk_unitree_robot/jsk_unitree_startup/launch/walk_notifier.launch b/jsk_unitree_robot/jsk_unitree_startup/launch/walk_notifier.launch
new file mode 100644
index 0000000000..a3ecc85a2d
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/launch/walk_notifier.launch
@@ -0,0 +1,34 @@
+<launch>
+
+  <arg name="network_interface" default="wlan0" />
+  <arg name="walk_notifier_info_path" default="/var/lib/robot/walk_notifier.yaml" />
+  <arg name="notify_interval" default="180" />
+  <arg name="input_image" default="/front_camera/output" />
+  <machine name="localhost" address="localhost" />
+  <machine name="nano2" user="unitree"
+           address='192.168.123.14'
+           env-loader="/opt/jsk/User/env.sh" />
+
+  <node name="location_node"
+        pkg="jsk_unitree_startup" type="location_node.py"
+        output="screen" >
+    <rosparam command="load" file="$(arg walk_notifier_info_path)"/>
+    <rosparam subst_value="true" >
+      network_interface: $(arg network_interface)
+    </rosparam>
+  </node>
+
+  <node name="walk_notifier"
+        pkg="jsk_unitree_startup" type="walk_notifier.py"
+        output="screen"
+        machine="nano2" >
+    <rosparam command="load" file="$(arg walk_notifier_info_path)"/>
+    <remap from="~get_location" to="/location_node/get_location" />
+    <remap from="~input_image" to="$(arg input_image)" />
+    <param name="~robot_name" command="python -c 'import socket; print(socket.gethostname())'" />
+    <rosparam subst_value="true" >
+      notify_interval: $(arg notify_interval)
+    </rosparam>
+  </node>
+
+</launch>
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/location_node.py b/jsk_unitree_robot/jsk_unitree_startup/scripts/location_node.py
new file mode 100755
index 0000000000..62601cfc6e
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/location_node.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+# -*- coding:utf-8 -*-
+
+import subprocess
+import re
+
+import requests
+import rospy
+from std_srvs.srv import Trigger
+from std_srvs.srv import TriggerResponse
+
+
+cell_number_re = re.compile(r"^Cell\s+(?P<cellnumber>.+)\s+-\s+Address:\s(?P<mac>.+)$")
+regexps = [
+    re.compile(r"^ESSID:\"(?P<essid>.*)\"$"),
+    re.compile(r"^Protocol:(?P<protocol>.+)$"),
+    re.compile(r"^Mode:(?P<mode>.+)$"),
+    re.compile(r"^Frequency:(?P<frequency>[\d.]+) (?P<frequency_units>.+) \(Channel (?P<channel>\d+)\)$"),
+    re.compile(r"^Encryption key:(?P<encryption>.+)$"),
+    re.compile(r"^Quality=(?P<signal_quality>\d+)/(?P<signal_total>\d+)\s+Signal level=(?P<signal_level_dBm>.+) d.+$"),
+    re.compile(r"^Signal level=(?P<signal_quality>\d+)/(?P<signal_total>\d+).*$"),
+]
+
+# Detect encryption type
+wpa_re = re.compile(r"IE:\ WPA\ Version\ 1$")
+wpa2_re = re.compile(r"IE:\ IEEE\ 802\.11i/WPA2\ Version\ 1$")
+
+
+def iwlist_scan(interface='wlan0'):
+    """Runs the comnmand to scan the list of networks.
+
+    Must run as super user.
+    Does not specify a particular device, so will scan all network devices.
+    """
+    cmd = ["iwlist", interface, "scan"]
+    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    points = proc.stdout.read().decode('utf-8')
+    return points
+
+
+def parse_iwlist(content):
+    """Parses the response from the command "iwlist scan"
+
+    """
+    cells = []
+    lines = content.split('\n')
+    for line in lines:
+        line = line.strip()
+        cellNumber = cell_number_re.search(line)
+        if cellNumber is not None:
+            cells.append(cellNumber.groupdict())
+            continue
+        wpa = wpa_re.search(line)
+        if wpa is not None:
+            cells[-1].update({'encryption': 'wpa'})
+        wpa2 = wpa2_re.search(line)
+        if wpa2 is not None:
+            cells[-1].update({'encryption': 'wpa2'})
+        for expression in regexps:
+            result = expression.search(line)
+            if result is not None:
+                if 'encryption' in result.groupdict():
+                    if result.groupdict()['encryption'] == 'on':
+                        cells[-1].update({'encryption': 'wep'})
+                    else:
+                        cells[-1].update({'encryption': 'off'})
+                else:
+                    cells[-1].update(result.groupdict())
+                continue
+    return cells
+
+
+class LocationNode(object):
+
+    def __init__(self):
+        self.network_interface = rospy.get_param('~network_interface', 'wlan0')
+        self.location_key = rospy.get_param('~location_key')
+        self.service = rospy.Service('~get_location',
+                                     Trigger, self.get_location)
+
+    def get_location(self, req):
+        aps = parse_iwlist(iwlist_scan(self.network_interface))
+        contents = [{"macAddress": str(ap['mac']), "age": 0}
+                    for ap in aps]
+        headers = {'Content-type': 'application/json'}
+        params = {'key': self.location_key,
+                  'language': 'ja'}
+        data = '{"wifiAccessPoints": ' + '[{}]'.format(contents) + '}'
+
+        response = requests.post('https://www.googleapis.com/geolocation/v1/geolocate',
+                                 params=params, headers=headers, data=data)
+        # {'location': {'lat': 35.7145647, 'lng': 139.766433}, 'accuracy': 19.612}
+        hoge = response.json()
+
+        lat = hoge['location']['lat']
+        lng = hoge['location']['lng']
+        # lat = 35.715106109567415
+        # lng = 139.77380123496505
+        response = requests.get(
+            'https://maps.googleapis.com/maps/api/geocode/json?latlng={},{}'.format(lat, lng),
+            headers=headers, params=params)
+        return TriggerResponse(success=True,
+                               message=response.text)
+
+
+if __name__ == '__main__':
+    rospy.init_node('location_node')
+    location_node = LocationNode()
+    rospy.spin()
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py b/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py
new file mode 100755
index 0000000000..9f82697c7e
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# -*- coding:utf-8 -*-
+
+import os
+import subprocess
+import time
+import re
+import json
+import tempfile
+
+import PIL.Image
+import sensor_msgs.msg
+from std_srvs.srv import Trigger
+import rospy
+import cv_bridge
+
+
+def send_mail(place, robot_name, sender_address, receiver_address, attachment=None):
+    """
+    Send mail with mailutils
+    """
+    mail_title = u"{}、お散歩中です。".format(robot_name)
+    message = u"お散歩してます。\\n今は{}を歩いているよ。".format(place)
+    cmd = u"echo -e '{}'".format(message)
+    cmd += u" | /usr/bin/mail -s '{}' -r {} {}".format(
+        mail_title, sender_address, receiver_address)
+    if attachment is not None:
+        cmd += ' -A {}'.format(attachment)
+    rospy.logerr('Executing: {}'.format(cmd.encode('utf-8')))
+    exit_code = subprocess.call(cmd.encode('utf-8'), shell=True)
+
+
+class WalkNotifier(object):
+
+    def __init__(self):
+        self.bridge = cv_bridge.CvBridge()
+        self.robot_name = rospy.get_param('~robot_name').strip()
+        self.sub = rospy.Subscriber('~input_image',
+                                    sensor_msgs.msg.Image,
+                                    callback=self.callback,
+                                    queue_size=1)
+        self.sender_address = rospy.get_param('~sender_address')
+        self.receiver_address = rospy.get_param('~receiver_address')
+        self.notify_interval = int(rospy.get_param('~notify_interval', 180))
+        rospy.wait_for_service('~get_location')
+        self.wait_image()
+
+    def callback(self, img_msg):
+        self.img = self.bridge.imgmsg_to_cv2(img_msg, desired_encoding='bgr8')
+
+    def wait_image(self):
+        self.img = None
+        rate = rospy.Rate(10)
+        while not rospy.is_shutdown() and self.img is None:
+            rate.sleep()
+            rospy.loginfo('[WalkMail] waiting image')
+
+    def get_place(self):
+        response = rospy.ServiceProxy('~get_location', Trigger)()
+        address = json.loads(response.message)
+        a = address['results'][0]['formatted_address']
+        print_address = " ".join(a.split(' ')[1:])
+
+        if self.img is not None:
+            _, img_path = tempfile.mkstemp(suffix='.jpg')
+            PIL.Image.fromarray(self.img[..., ::-1]).save(img_path)
+            send_mail(print_address, self.robot_name,
+                      self.sender_address, self.receiver_address,
+                      img_path)
+            os.remove(img_path)
+        else:
+            send_mail(print_address, self.robot_name,
+                      self.sender_address, self.receiver_address,
+                      img_path)
+
+    def run(self):
+        rate = rospy.Rate(10)
+        while not rospy.is_shutdown():
+            rate.sleep()
+            notifier.get_place()
+            time.sleep(self.notify_interval)
+
+
+if __name__ == '__main__':
+    rospy.init_node('walk_notifier')
+    notifier = WalkNotifier()
+    notifier.run()

From d3d98cc87445d6b68f8dba868319a64cdb201a48 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sun, 7 Aug 2022 20:59:44 +0900
Subject: [PATCH 37/77] [jsk_unitree_startup/cross] Add env.sh for machine tag

---
 jsk_unitree_robot/cross/build_user.sh          | 1 +
 jsk_unitree_robot/cross/startup_scripts/env.sh | 4 ++++
 2 files changed, 5 insertions(+)
 create mode 100755 jsk_unitree_robot/cross/startup_scripts/env.sh

diff --git a/jsk_unitree_robot/cross/build_user.sh b/jsk_unitree_robot/cross/build_user.sh
index 53c53356bc..dc0988d23d 100755
--- a/jsk_unitree_robot/cross/build_user.sh
+++ b/jsk_unitree_robot/cross/build_user.sh
@@ -60,3 +60,4 @@ docker run -it --rm \
         --cmake-args -DCATKIN_ENABLE_TESTING=FALSE \
     " 2>&1 | tee ${TARGET_MACHINE}_build_user.log
 cp ${PWD}/startup_scripts/user_setup.bash ${SOURCE_ROOT}/
+cp ${PWD}/startup_scripts/env.sh ${SOURCE_ROOT}/
diff --git a/jsk_unitree_robot/cross/startup_scripts/env.sh b/jsk_unitree_robot/cross/startup_scripts/env.sh
new file mode 100755
index 0000000000..d158436b47
--- /dev/null
+++ b/jsk_unitree_robot/cross/startup_scripts/env.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+source /opt/jsk/User/user_setup.bash
+exec "$@"

From e84bafd8ba84f8d7670b2b458390370b80a6114e Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sun, 7 Aug 2022 21:18:15 +0900
Subject: [PATCH 38/77] [jsk_unitree_startup] Add walk_notifier application

---
 .../apps/unitree_apps.installed               |   2 +
 .../apps/walk_notifier/walk_notifier.app      |   5 +++
 .../walk_notifier/walk_notifier.interface     |   2 +
 .../apps/walk_notifier/walk_notifier.png      | Bin 0 -> 84233 bytes
 .../apps/walk_notifier/walk_notifier.xml      |   6 +++
 .../autostart/jsk_startup.sh                  |   1 +
 .../launch/get_location.launch                |  15 +++++++
 .../launch/walk_notifier.launch               |  18 +-------
 .../scripts/walk_notifier.py                  |  39 ++++++++++++------
 9 files changed, 59 insertions(+), 29 deletions(-)
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.app
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.interface
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.png
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.xml
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/launch/get_location.launch

diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/unitree_apps.installed b/jsk_unitree_robot/jsk_unitree_startup/apps/unitree_apps.installed
index 6bafcd68ef..ad52081ce4 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/apps/unitree_apps.installed
+++ b/jsk_unitree_robot/jsk_unitree_startup/apps/unitree_apps.installed
@@ -3,3 +3,5 @@ apps:
     display: go1 watch dog
   - app: jsk_unitree_startup/lead_teleop
     display: go1 lead teleop
+  - app: jsk_unitree_startup/walk_notifier
+    display: go1 walk notifier
diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.app b/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.app
new file mode 100644
index 0000000000..41bc3f5339
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.app
@@ -0,0 +1,5 @@
+display: Walk Notifier
+platform: go1
+launch: jsk_unitree_startup/walk_notifier.xml
+interface: jsk_unitree_startup/walk_notifier.interface
+icon: jsk_unitree_startup/walk_notifier.png
diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.interface b/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.interface
new file mode 100644
index 0000000000..044105d644
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.interface
@@ -0,0 +1,2 @@
+published_topics: {}
+subscribed_topics: {}
diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.png b/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.png
new file mode 100644
index 0000000000000000000000000000000000000000..702466a6fc59ff33b7e153b208419a69eb949b7a
GIT binary patch
literal 84233
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

literal 0
HcmV?d00001

diff --git a/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.xml b/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.xml
new file mode 100644
index 0000000000..8093ee49b8
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/apps/walk_notifier/walk_notifier.xml
@@ -0,0 +1,6 @@
+<launch>
+
+  <include file="$(find jsk_unitree_startup)/launch/walk_notifier.launch" >
+  </include>
+
+</launch>
diff --git a/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh b/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh
index 0e96a8e217..a028fba255 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh
+++ b/jsk_unitree_robot/jsk_unitree_startup/autostart/jsk_startup.sh
@@ -17,6 +17,7 @@ if [ "$ROS_IP" == "192.168.123.161" ];then
     roslaunch --screen sound_play soundplay_node.launch sound_play:=robotsound &
     roslaunch --screen jsk_unitree_startup rwt_app_chooser.launch &
     roslaunch --screen jsk_unitree_startup rosserial_node.launch &
+    roslaunch --screen jsk_unitree_startup get_location.launch &
     roslaunch --screen respeaker_ros sample_respeaker.launch language:=ja-JP publish_tf:=false launch_soundplay:=false &
 fi
 
diff --git a/jsk_unitree_robot/jsk_unitree_startup/launch/get_location.launch b/jsk_unitree_robot/jsk_unitree_startup/launch/get_location.launch
new file mode 100644
index 0000000000..f77874b3c4
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/launch/get_location.launch
@@ -0,0 +1,15 @@
+<launch>
+
+  <arg name="network_interface" default="wlan0" />
+  <arg name="google_map_location_key_path" default="/var/lib/robot/google_map_location_key.yaml" />
+
+  <node name="location_node"
+        pkg="jsk_unitree_startup" type="location_node.py"
+        output="screen" >
+    <rosparam command="load" file="$(arg google_map_location_key_path)"/>
+    <rosparam subst_value="true" >
+      network_interface: $(arg network_interface)
+    </rosparam>
+  </node>
+
+</launch>
diff --git a/jsk_unitree_robot/jsk_unitree_startup/launch/walk_notifier.launch b/jsk_unitree_robot/jsk_unitree_startup/launch/walk_notifier.launch
index a3ecc85a2d..d18374c75d 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/launch/walk_notifier.launch
+++ b/jsk_unitree_robot/jsk_unitree_startup/launch/walk_notifier.launch
@@ -1,31 +1,15 @@
 <launch>
 
-  <arg name="network_interface" default="wlan0" />
   <arg name="walk_notifier_info_path" default="/var/lib/robot/walk_notifier.yaml" />
   <arg name="notify_interval" default="180" />
   <arg name="input_image" default="/front_camera/output" />
-  <machine name="localhost" address="localhost" />
-  <machine name="nano2" user="unitree"
-           address='192.168.123.14'
-           env-loader="/opt/jsk/User/env.sh" />
-
-  <node name="location_node"
-        pkg="jsk_unitree_startup" type="location_node.py"
-        output="screen" >
-    <rosparam command="load" file="$(arg walk_notifier_info_path)"/>
-    <rosparam subst_value="true" >
-      network_interface: $(arg network_interface)
-    </rosparam>
-  </node>
 
   <node name="walk_notifier"
         pkg="jsk_unitree_startup" type="walk_notifier.py"
-        output="screen"
-        machine="nano2" >
+        output="screen" >
     <rosparam command="load" file="$(arg walk_notifier_info_path)"/>
     <remap from="~get_location" to="/location_node/get_location" />
     <remap from="~input_image" to="$(arg input_image)" />
-    <param name="~robot_name" command="python -c 'import socket; print(socket.gethostname())'" />
     <rosparam subst_value="true" >
       notify_interval: $(arg notify_interval)
     </rosparam>
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py b/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py
index 9f82697c7e..3eeb2d52f3 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py
@@ -20,21 +20,29 @@ def send_mail(place, robot_name, sender_address, receiver_address, attachment=No
     Send mail with mailutils
     """
     mail_title = u"{}、お散歩中です。".format(robot_name)
-    message = u"お散歩してます。\\n今は{}を歩いているよ。".format(place)
-    cmd = u"echo -e '{}'".format(message)
-    cmd += u" | /usr/bin/mail -s '{}' -r {} {}".format(
+    message = u"お散歩してます。"
+    if place is not None:
+        message += u"\n今は{}を歩いているよ。".format(place)
+    cmd = u"mail -s '{}' -r {} {}".format(
         mail_title, sender_address, receiver_address)
     if attachment is not None:
         cmd += ' -A {}'.format(attachment)
-    rospy.logerr('Executing: {}'.format(cmd.encode('utf-8')))
-    exit_code = subprocess.call(cmd.encode('utf-8'), shell=True)
+    cmd = ['mail', '-s', mail_title.encode('utf-8'),
+           '-r', sender_address,
+           receiver_address]
+    rospy.loginfo('Executing: {}'.format(' '.join(cmd)))
+    process = subprocess.Popen(cmd,
+                               stdin=subprocess.PIPE,
+                               universal_newlines=True)
+    process.communicate(message.encode('utf-8'))
+    process.wait()
 
 
 class WalkNotifier(object):
 
     def __init__(self):
         self.bridge = cv_bridge.CvBridge()
-        self.robot_name = rospy.get_param('~robot_name').strip()
+        self.robot_name = rospy.get_param('~robot_name', 'unitree').strip()
         self.sub = rospy.Subscriber('~input_image',
                                     sensor_msgs.msg.Image,
                                     callback=self.callback,
@@ -56,11 +64,14 @@ def wait_image(self):
             rospy.loginfo('[WalkMail] waiting image')
 
     def get_place(self):
-        response = rospy.ServiceProxy('~get_location', Trigger)()
-        address = json.loads(response.message)
-        a = address['results'][0]['formatted_address']
-        print_address = " ".join(a.split(' ')[1:])
-
+        try:
+            response = rospy.ServiceProxy('~get_location', Trigger)()
+            address = json.loads(response.message)
+            a = address['results'][0]['formatted_address']
+            print_address = " ".join(a.split(' ')[1:])
+        except Exception as e:
+            rospy.logerr('Error: {}'.format(str(e)))
+            print_address = None
         if self.img is not None:
             _, img_path = tempfile.mkstemp(suffix='.jpg')
             PIL.Image.fromarray(self.img[..., ::-1]).save(img_path)
@@ -77,7 +88,11 @@ def run(self):
         rate = rospy.Rate(10)
         while not rospy.is_shutdown():
             rate.sleep()
-            notifier.get_place()
+            try:
+                notifier.get_place()
+            except Exception as e:
+                rospy.logerr('Error: {}'.format(str(e)))
+                continue
             time.sleep(self.notify_interval)
 
 

From 11964cf990213b5b4be4b6d99e43eca6be450c60 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sun, 7 Aug 2022 21:33:42 +0900
Subject: [PATCH 39/77] [jsk_unitree_startup] Add wlan2 settings for sparky

---
 .../jsk_unitree_startup/config/dhcpcd.conf            | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/jsk_unitree_startup/config/dhcpcd.conf b/jsk_unitree_robot/jsk_unitree_startup/config/dhcpcd.conf
index c2d1530f29..77b0d64c07 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/config/dhcpcd.conf
+++ b/jsk_unitree_robot/jsk_unitree_startup/config/dhcpcd.conf
@@ -76,4 +76,13 @@ nohook wpa_supplicant
 interface usb0
 metric 100
 static domain_name_servers=8.8.8.8
-###############################################
\ No newline at end of file
+###############################################
+
+################################################
+# For sparky
+# This enables Unitree(sparky) to connect the Internet.
+################################################
+interface wlan2
+metric 101
+static domain_name_servers=8.8.8.8
+###############################################

From 5813abd6fde89b6551b111a958aaf3174bae7cda Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sun, 7 Aug 2022 22:10:17 +0900
Subject: [PATCH 40/77] [jsk_unitree_startup/cross] Install mailutils

---
 .../cross/repos/ros1_dependencies.repos       |  6 ++++++
 .../1037-mailutils                            | 19 +++++++++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100755 jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils

diff --git a/jsk_unitree_robot/cross/repos/ros1_dependencies.repos b/jsk_unitree_robot/cross/repos/ros1_dependencies.repos
index 2983607027..a9ff0f4105 100644
--- a/jsk_unitree_robot/cross/repos/ros1_dependencies.repos
+++ b/jsk_unitree_robot/cross/repos/ros1_dependencies.repos
@@ -203,3 +203,9 @@ repositories:
   festlex-poslex:
     type: tar
     url: http://archive.ubuntu.com/ubuntu/pool/universe/f/festlex-poslex/festlex-poslex_2.4.orig.tar.gz
+  mailutils:
+    type: tar
+    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.4.orig.tar.xz
+  mailutils/debian:
+    type: tar
+    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.4-1.debian.tar.xz
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
new file mode 100755
index 0000000000..510b004c88
--- /dev/null
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
@@ -0,0 +1,19 @@
+#!/bin/bash
+set -xeu -o pipefail
+
+DEBIAN_DIR=/home/user/ros1_dependencies_sources/src/mailutils/debian/debian
+SOURCE_DIR=/home/user/ros1_dependencies_sources/src/mailutils/mailutils-3.4
+
+#
+# constantly does not have patches
+#
+cd ${DEBIAN_DIR}/patches
+for patch_file in $(grep -v ^# series); do
+    OUT="$(patch -p1 --forward --directory ${SOURCE_DIR} < ${patch_file} | tee /dev/tty)" || echo "${OUT}" | grep "Skipping patch" -q || (echo "$OUT" && false) || echo "OK"
+done
+
+cd ${SOURCE_DIR}
+
+./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
+
+make install

From 8758d438a9d1eac1c9fa6f3f70194da5e9eba2cf Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sun, 7 Aug 2022 23:24:15 +0900
Subject: [PATCH 41/77] [jsk_unitree_startup] Enable wlan0

---
 jsk_unitree_robot/cross/install.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index a2d184c6ee..349ec77720 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -113,7 +113,11 @@ function copy_data () {
     if [[ "${hostname}" == "192.168.123.161" ]]; then
         sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find jsk_unitree_startup)/config/dhcpcd.conf /etc/dhcpcd.conf"
         sshpass -p $PASS ssh -t ${user}@${hostname} "sudo systemctl restart dhcpcd"
+
+        # enable wlan0
+        sshpass -p $PASS ssh -t ${user}@${hostname} "sed -i 's/sudo ifconfig wlan0 down/# sudo ifconfig wlan0 down/g' /home/pi/Unitree/autostart/configNetwork/configNetwork.sh"
     fi
+
     set +x
 }
 

From 6e47211ca589970ce05958408e707bb9f107e8f8 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 8 Aug 2022 00:31:12 +0900
Subject: [PATCH 42/77] [jsk_unitree_startup/install] passthrough password

---
 jsk_unitree_robot/cross/install.sh | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index 349ec77720..542eec10e0 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -79,7 +79,7 @@ function copy_data () {
     echo "Check user id for /dev/ttyACM0 etc"
     echo "==="
     sshpass -p $PASS ssh -t ${user}@${hostname} bash -c 'id'
-    sshpass -p $PASS ssh -t ${user}@${hostname} bash -c "groups | grep dialout || (set -x; sudo usermod -a -G dialout ${user})"
+    sshpass -p $PASS ssh -t ${user}@${hostname} bash -c "groups | grep dialout || (set -x; echo $PASS | sudo -S usermod -a -G dialout ${user})"
     echo "==="
 
     # check if we have jsk_startup in .startlist
@@ -90,7 +90,7 @@ function copy_data () {
     # check if we have /opt/jsk
     set -x
     sshpass -p $PASS ssh -t ${user}@${hostname} "test -e /opt/jsk" || \
-        sshpass -p $PASS ssh -t ${user}@${hostname} "sudo mkdir -p /opt/jsk && sudo chown -R \$(id -u \${USER}):\$(id -g \${USER}) /opt/jsk && ls -al /opt/jsk"
+        sshpass -p $PASS ssh -t ${user}@${hostname} "echo $PASS | sudo -S mkdir -p /opt/jsk && sudo chown -R \$(id -u \${USER}):\$(id -g \${USER}) /opt/jsk && ls -al /opt/jsk"
 
     rsync --rsh="/usr/bin/sshpass -p $PASS ssh -o StrictHostKeyChecking=no -l ${user}" -avz --delete --delete-excluded --exclude "*.pyc" --exclude "^logs/" ${TARGET_MACHINE}_${TARGET_DIRECTORY}/ ${hostname}:/opt/jsk/${TARGET_DIRECTORY}
     if [[ "${TARGET_DIRECTORY}" == "User" ]]; then
@@ -104,15 +104,15 @@ function copy_data () {
 
         # update udev
         # respeaker_ros
-        sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find respeaker_ros)/config/60-respeaker.rules /etc/udev/rules.d/60-respeaker.rules"
+        sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; echo $PASS | sudo -S cp -f \$(rospack find respeaker_ros)/config/60-respeaker.rules /etc/udev/rules.d/60-respeaker.rules"
         #
-        sshpass -p $PASS ssh -t ${user}@${hostname} "ls -al /etc/udev/rules.d/; sudo systemctl restart udev"
+        sshpass -p $PASS ssh -t ${user}@${hostname} "ls -al /etc/udev/rules.d/; echo $PASS | sudo -S systemctl restart udev"
     fi
 
     # enable Internet with USB LTE module
     if [[ "${hostname}" == "192.168.123.161" ]]; then
-        sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; sudo cp -f \$(rospack find jsk_unitree_startup)/config/dhcpcd.conf /etc/dhcpcd.conf"
-        sshpass -p $PASS ssh -t ${user}@${hostname} "sudo systemctl restart dhcpcd"
+        sshpass -p $PASS ssh -t ${user}@${hostname} "source /opt/jsk/User/user_setup.bash; echo $PASS | sudo -S cp -f \$(rospack find jsk_unitree_startup)/config/dhcpcd.conf /etc/dhcpcd.conf"
+        sshpass -p $PASS ssh -t ${user}@${hostname} "echo $PASS | sudo -S systemctl restart dhcpcd"
 
         # enable wlan0
         sshpass -p $PASS ssh -t ${user}@${hostname} "sed -i 's/sudo ifconfig wlan0 down/# sudo ifconfig wlan0 down/g' /home/pi/Unitree/autostart/configNetwork/configNetwork.sh"

From 6cf0090e4d07b376837b301f11976718bcfc3944 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 8 Aug 2022 00:52:06 +0900
Subject: [PATCH 43/77] [jsk_unitree_startup/install] Modified owner of
 /var/mail/${USER}

---
 jsk_unitree_robot/cross/install.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index 542eec10e0..6a3cf3468b 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -92,6 +92,10 @@ function copy_data () {
     sshpass -p $PASS ssh -t ${user}@${hostname} "test -e /opt/jsk" || \
         sshpass -p $PASS ssh -t ${user}@${hostname} "echo $PASS | sudo -S mkdir -p /opt/jsk && sudo chown -R \$(id -u \${USER}):\$(id -g \${USER}) /opt/jsk && ls -al /opt/jsk"
 
+    # check if we have /var/mail/${user}
+    sshpass -p $PASS ssh -t ${user}@${hostname} "touch /var/mail/${user}" && \
+        sshpass -p $PASS ssh -t ${user}@${hostname} "echo $PASS | sudo -S sudo chown -R \$(id -u \${USER}):\$(id -g \${USER}) /var/mail/${user}"
+
     rsync --rsh="/usr/bin/sshpass -p $PASS ssh -o StrictHostKeyChecking=no -l ${user}" -avz --delete --delete-excluded --exclude "*.pyc" --exclude "^logs/" ${TARGET_MACHINE}_${TARGET_DIRECTORY}/ ${hostname}:/opt/jsk/${TARGET_DIRECTORY}
     if [[ "${TARGET_DIRECTORY}" == "User" ]]; then
         rsync --rsh="/usr/bin/sshpass -p $PASS ssh -o StrictHostKeyChecking=no -l ${user}" -avz --delete --delete-excluded ../jsk_unitree_startup/autostart/ ${hostname}:Unitree/autostart/jsk_startup

From c2cb48c485186c8e2b47f9007065b503e081964b Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 8 Aug 2022 00:59:13 +0900
Subject: [PATCH 44/77] [jsk_unitree_startup/WalkNotifier] Enable attachment

---
 jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py b/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py
index 3eeb2d52f3..68c6c3bce0 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/walk_notifier.py
@@ -30,6 +30,8 @@ def send_mail(place, robot_name, sender_address, receiver_address, attachment=No
     cmd = ['mail', '-s', mail_title.encode('utf-8'),
            '-r', sender_address,
            receiver_address]
+    if attachment is not None:
+        cmd += ['-A', attachment]
     rospy.loginfo('Executing: {}'.format(' '.join(cmd)))
     process = subprocess.Popen(cmd,
                                stdin=subprocess.PIPE,

From 95fdfa54bf87d4016172f37446f0a75ee923779b Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 8 Aug 2022 01:25:59 +0900
Subject: [PATCH 45/77] [jsk_unitree_startup] Update version of mailutils

---
 jsk_unitree_robot/cross/repos/ros1_dependencies.repos         | 4 ++--
 .../cross/ros1_dependencies_build_scripts/1037-mailutils      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/jsk_unitree_robot/cross/repos/ros1_dependencies.repos b/jsk_unitree_robot/cross/repos/ros1_dependencies.repos
index a9ff0f4105..9fddaa0137 100644
--- a/jsk_unitree_robot/cross/repos/ros1_dependencies.repos
+++ b/jsk_unitree_robot/cross/repos/ros1_dependencies.repos
@@ -205,7 +205,7 @@ repositories:
     url: http://archive.ubuntu.com/ubuntu/pool/universe/f/festlex-poslex/festlex-poslex_2.4.orig.tar.gz
   mailutils:
     type: tar
-    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.4.orig.tar.xz
+    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.7.orig.tar.xz
   mailutils/debian:
     type: tar
-    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.4-1.debian.tar.xz
+    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.7-2.1.debian.tar.xz
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
index 510b004c88..7c44f1dfa2 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
@@ -2,7 +2,7 @@
 set -xeu -o pipefail
 
 DEBIAN_DIR=/home/user/ros1_dependencies_sources/src/mailutils/debian/debian
-SOURCE_DIR=/home/user/ros1_dependencies_sources/src/mailutils/mailutils-3.4
+SOURCE_DIR=/home/user/ros1_dependencies_sources/src/mailutils/mailutils-3.7
 
 #
 # constantly does not have patches

From 15260f70a28609978983d32aa0e9427aad2d1902 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 8 Aug 2022 03:01:29 +0900
Subject: [PATCH 46/77] [jsk_unitree_startup/cross] Disable python for
 mailutils

---
 .../cross/ros1_dependencies_build_scripts/1037-mailutils        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
index 7c44f1dfa2..b4043d0cb6 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
@@ -14,6 +14,6 @@ done
 
 cd ${SOURCE_DIR}
 
-./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
+./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies --disable-python
 
 make install

From fca125f619f6d4e574b07b563c9e14075cbb42c9 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 8 Aug 2022 10:52:19 +0900
Subject: [PATCH 47/77] [jsk_unitree_startup/install.sh] Use sudo for touch
 /var/mail/unitree

---
 jsk_unitree_robot/cross/install.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index ea78fabe9d..de8f2639e8 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -101,7 +101,7 @@ function copy_data () {
         sshpass -p $PASS ssh -t ${user}@${hostname} "echo $PASS | sudo -S mkdir -p /opt/jsk && sudo chown -R \$(id -u \${USER}):\$(id -g \${USER}) /opt/jsk && ls -al /opt/jsk"
 
     # check if we have /var/mail/${user}
-    sshpass -p $PASS ssh -t ${user}@${hostname} "touch /var/mail/${user}" && \
+    sshpass -p $PASS ssh -t ${user}@${hostname} "echo $PASS | sudo -S touch /var/mail/${user}" && \
         sshpass -p $PASS ssh -t ${user}@${hostname} "echo $PASS | sudo -S sudo chown -R \$(id -u \${USER}):\$(id -g \${USER}) /var/mail/${user}"
 
     rsync --rsh="sshpass -p $PASS ssh -o StrictHostKeyChecking=no -l ${user}" -avz --delete --delete-excluded --exclude "*.pyc" --exclude "^logs/" ${TARGET_MACHINE}_${TARGET_DIRECTORY}/ ${hostname}:/opt/jsk/${TARGET_DIRECTORY}

From d541c813132712f3856f3e0e3de64ab4c50abe75 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 8 Aug 2022 12:44:45 +0900
Subject: [PATCH 48/77] [jsk_unitree_startup] Add Walk notifier's README

---
 .../jsk_unitree_startup/README.md             | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 jsk_unitree_robot/jsk_unitree_startup/README.md

diff --git a/jsk_unitree_robot/jsk_unitree_startup/README.md b/jsk_unitree_robot/jsk_unitree_startup/README.md
new file mode 100644
index 0000000000..39c1410bf4
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/README.md
@@ -0,0 +1,26 @@
+# jsk_unitree_startup
+
+## app_manager
+
+The unitree launches various apps via [app_manager](https://github.com/pr2/app_manager).
+
+You can launch the app from the browser by accessing this [url](http://192.168.123.161:8000/rwt_app_chooser/).
+
+### Walk Notifier
+
+Send an email with the location of the walk and a camera image of the walk.
+
+![](./apps/walk_notifier/walk_notifier.png)
+
+#### prerequirement
+
+The key for google map needs to be placed in `/var/lib/robot/google_map_location_key.yaml` (pi@192.168.123.161) with 'location_key' as the key.
+
+For JSK members, the yaml file are available at [Google Drive](https://drive.google.com/file/d/1D867WB70GDEN0g9IKXfoTHk-5MUJFiuf/view?usp=sharing)
+
+Also, place a yaml file with the email addresses of the sender and receiver in `/var/lib/robot/walk_notifier.yaml`.
+
+```
+sender_address: hogehoge@some.mail.com
+receiver_address: foo@some.mail.com
+```

From 722b3fbcda1d9e99f8b9b9cff3581cec2a9f5e0a Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Fri, 5 Aug 2022 00:11:29 +0900
Subject: [PATCH 49/77] [jsk_unitree_startup/cross] Add y or n

---
 jsk_unitree_robot/cross/compress.sh | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/jsk_unitree_robot/cross/compress.sh b/jsk_unitree_robot/cross/compress.sh
index 57a097320e..fd8a79096b 100755
--- a/jsk_unitree_robot/cross/compress.sh
+++ b/jsk_unitree_robot/cross/compress.sh
@@ -2,12 +2,27 @@
 
 if [ -e "arm64v8_User" ]; then
     if [ -e "arm64v8_User.tar.gz" ]; then
+        echo "WARNING: Compressed arm64v8_User.tar.gz is found."
+        read -p "WARNING: Are you sure to continue [y/N] ? " -n 1 -r
+        echo    # (optional) move to a new line
+        if [[ $REPLY =~ ^[Yy]$ ]]; then
+            tar -zcvf arm64v8_User.tar.gz arm64v8_User
+        fi
+    else
         tar -zcvf arm64v8_User.tar.gz arm64v8_User
     fi
 fi
 
 if [ -e "arm64v8_System" ]; then
     if [ -e "arm64v8_System.tar.gz" ]; then
+        echo "WARNING: Compressed arm64v8_System.tar.gz is found."
+        read -p "WARNING: Are you sure to continue [y/N] ? " -n 1 -r
+        echo    # (optional) move to a new line
+        if [[ $REPLY =~ ^[Yy]$ ]]; then
+            chmod 644 arm64v8_System/ros1_inst/share/pr2eus/*.l
+            tar -zcvf arm64v8_System.tar.gz arm64v8_System
+        fi
+    else
         chmod 644 arm64v8_System/ros1_inst/share/pr2eus/*.l
         tar -zcvf arm64v8_System.tar.gz arm64v8_System
     fi

From 749f4869dd015bd0e86eb33be7d8f6fc5047ee5f Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 8 Aug 2022 20:09:00 +0900
Subject: [PATCH 50/77] [jsk_perception_3rdparty] Passthrough password

---
 jsk_unitree_robot/cross/install.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index de8f2639e8..767bb10b03 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -68,8 +68,8 @@ function copy_data () {
 
     if [[ "${TARGET_DIRECTORY}" == "System" ]]; then
         sshpass -p 123 scp ${TARGET_MACHINE}_${TARGET_DIRECTORY}/sitecustomize.py ${user}@${hostname}:/tmp/sitecustomize.py
-        sshpass -p $PASS ssh -t ${user}@${hostname} "sudo cp -f /tmp/sitecustomize.py /usr/lib/python2.7/sitecustomize.py"
-        sshpass -p $PASS ssh -t ${user}@${hostname} "sudo cp -f /tmp/sitecustomize.py /usr/lib/python3/sitecustomize.py"
+        sshpass -p $PASS ssh -t ${user}@${hostname} "echo $PASS | sudo -S cp -f /tmp/sitecustomize.py /usr/lib/python2.7/sitecustomize.py"
+        sshpass -p $PASS ssh -t ${user}@${hostname} "echo $PASS | sudo -S cp -f /tmp/sitecustomize.py /usr/lib/python3/sitecustomize.py"
     fi
 
     # cehck disk space

From e1c68e5b9a16a5abd70ea7ee3388d3ada333f5a0 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 8 Aug 2022 23:24:20 +0900
Subject: [PATCH 51/77] [jsk_unitree_startup] Fixed start_app's rosservice
 names

---
 .../jsk_unitree_startup/launch/unitree_bringup.launch         | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/jsk_unitree_robot/jsk_unitree_startup/launch/unitree_bringup.launch b/jsk_unitree_robot/jsk_unitree_startup/launch/unitree_bringup.launch
index 4557b8eaee..0534bb9072 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/launch/unitree_bringup.launch
+++ b/jsk_unitree_robot/jsk_unitree_startup/launch/unitree_bringup.launch
@@ -34,13 +34,13 @@
   <include file="$(find app_manager)/launch/app_manager.launch" />
 
   <!-- start lead teleop.launch -->
-  <node name="rosservice"
+  <node name="rosservice_lead_teleop"
         pkg="rosservice" type="rosservice"
         args="call --wait /robot/start_app 'name: jsk_unitree_startup/lead_teleop'"
         output="screen" />
 
   <!-- start emotion_reaction.launch -->
-  <node name="rosservice"
+  <node name="rosservice_emotion_reaction"
         pkg="rosservice" type="rosservice"
         args="call --wait /robot/start_app 'name: jsk_unitree_startup/emotion_reaction'"
         output="screen" />

From 14022cd2d8cf315c21cacc5394302a1d1fab5044 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sat, 27 Aug 2022 18:37:15 +0900
Subject: [PATCH 52/77] Revert "[jsk_unitree_startup] Update version of
 mailutils"

This reverts commit 95fdfa54bf87d4016172f37446f0a75ee923779b.
---
 jsk_unitree_robot/cross/repos/ros1_dependencies.repos         | 4 ++--
 .../cross/ros1_dependencies_build_scripts/1037-mailutils      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/jsk_unitree_robot/cross/repos/ros1_dependencies.repos b/jsk_unitree_robot/cross/repos/ros1_dependencies.repos
index 9fddaa0137..a9ff0f4105 100644
--- a/jsk_unitree_robot/cross/repos/ros1_dependencies.repos
+++ b/jsk_unitree_robot/cross/repos/ros1_dependencies.repos
@@ -205,7 +205,7 @@ repositories:
     url: http://archive.ubuntu.com/ubuntu/pool/universe/f/festlex-poslex/festlex-poslex_2.4.orig.tar.gz
   mailutils:
     type: tar
-    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.7.orig.tar.xz
+    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.4.orig.tar.xz
   mailutils/debian:
     type: tar
-    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.7-2.1.debian.tar.xz
+    url: http://archive.ubuntu.com/ubuntu/pool/universe/m/mailutils/mailutils_3.4-1.debian.tar.xz
diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
index b4043d0cb6..d95efeaefe 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
@@ -2,7 +2,7 @@
 set -xeu -o pipefail
 
 DEBIAN_DIR=/home/user/ros1_dependencies_sources/src/mailutils/debian/debian
-SOURCE_DIR=/home/user/ros1_dependencies_sources/src/mailutils/mailutils-3.7
+SOURCE_DIR=/home/user/ros1_dependencies_sources/src/mailutils/mailutils-3.4
 
 #
 # constantly does not have patches

From 69874b1f53f712ebcfeea76f1e85c720625e89b6 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Sat, 27 Aug 2022 18:37:19 +0900
Subject: [PATCH 53/77] Revert "[jsk_unitree_startup/cross] Disable python for
 mailutils"

This reverts commit 15260f70a28609978983d32aa0e9427aad2d1902.
---
 .../cross/ros1_dependencies_build_scripts/1037-mailutils        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
index d95efeaefe..510b004c88 100755
--- a/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
+++ b/jsk_unitree_robot/cross/ros1_dependencies_build_scripts/1037-mailutils
@@ -14,6 +14,6 @@ done
 
 cd ${SOURCE_DIR}
 
-./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies --disable-python
+./configure --prefix=/opt/jsk/${INSTALL_ROOT}/ros1_dependencies
 
 make install

From f13a43d536696a23700734c71bc0401df9573366 Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Tue, 26 Jul 2022 10:58:38 +0900
Subject: [PATCH 54/77] enable to send mail

---
 .../scripts/smach_to_mail.py                  | 110 ++++++++++++++++++
 1 file changed, 110 insertions(+)
 create mode 100644 jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
new file mode 100644
index 0000000000..4a038b4281
--- /dev/null
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+
+import base64
+import cv2
+import datetime
+import imghdr
+import pickle
+import rospy
+import time
+
+from cv_bridge import CvBridge
+from jsk_robot_startup.msg import Email
+from jsk_robot_startup.msg import EmailBody
+from sensor_msgs.msg import CompressedImage
+from smach_msgs.msg import SmachContainerStatus
+
+
+class SmachToMail():
+
+    def __init__(self):
+        rospy.init_node('server_name')
+        # it should be 'smach_to_mail', but 'server_name'
+        # is the default name of smach_ros
+        self.pub = rospy.Publisher("/email", Email, queue_size=10)
+        rospy.Subscriber(
+            "~smach/container_status", SmachContainerStatus, self._status_cb)
+        self.bridge = CvBridge()
+        self.smach_state_list = []  # for status list
+        self.sender_address = "tsukamoto@jsk.imi.i.u-tokyo.ac.jp"
+        self.receiver_address = "tsukamoto@jsk.imi.i.u-tokyo.ac.jp"
+
+    def _status_cb(self, msg):
+        '''
+        Recording starts when smach_state becomes start.
+        '''
+        if len(msg.active_states) == 0:
+            return
+        file_path = None
+        status_str = ', '.join(msg.active_states);
+        local_data_str = pickle.loads(msg.local_data)
+        info_str = msg.info
+        print("status -> {}".format(status_str))
+        print("description_str -> {}".format(local_data_str['DESCRIPTION']))
+
+        if status_str == "START" or "INIT":
+            self.smach_state_list = []
+        if local_data_str['IMAGE']:
+            imgmsg = CompressedImage()
+            imgmsg.deserialize(base64.b64decode(local_data_str['IMAGE']))
+            cv_image = self.bridge.compressed_imgmsg_to_cv2(imgmsg, "bgr8")
+            rospy.logerr(
+                "cv image type:{}".format(imghdr.what(None, cv_image)))  # for debugging
+            dt_now = datetime.datetime.now()   # header should be used??
+
+            file_path = "/tmp/{}_{}.jpg".format(
+                status_str.lower(), dt_now.strftime('%y%m%d%H%M%S'))
+            rospy.loginfo("filepath:{}".format(file_path))
+            # if (next((x for x in self.smach_state_list if x["IMAGE"] == file_path), None)):
+            #     rospy.loginfo("same file name!!!!")
+            # else:
+            #     rospy.loginfo("not same file name!!!")
+            cv2.imwrite(file_path, cv_image)
+            # cv2.imshow("Image", input_image)
+            cv2.waitKey(2)
+        else:
+            file_path = ""
+
+        status_dict = {'DESCRIPTION': local_data_str['DESCRIPTION'],
+                       'IMAGE': file_path}  # dict is complicated?
+        self.smach_state_list.append(status_dict)
+        print(self.smach_state_list)
+        print("info_str -> {}".format(info_str))
+
+        if status_str == "END" or "FINISH":
+            rospy.loginfo("END!!")
+            self._send_mail()
+
+    def _send_mail(self):
+        email_msg = Email()
+        email_msg.body = []
+        changeline = EmailBody()
+        changeline.type = 'html'
+        changeline.message = "<br>"
+        for x in self.smach_state_list:
+            description = EmailBody()
+            image = EmailBody()
+            description.type = 'text'
+            description.message = x['DESCRIPTION']
+            email_msg.body.append(description)
+            email_msg.body.append(changeline)
+            if x['IMAGE']:
+                image.type = 'img'
+                image.img_size = 50
+                image.file_path = x['IMAGE']
+                email_msg.body.append(image)
+                email_msg.body.append(changeline)
+        rospy.loginfo("body:{}".format(email_msg.body))
+
+        email_msg.subject = 'Smach mail test'
+
+        email_msg.sender_address = self.sender_address
+        email_msg.receiver_address = self.receiver_address
+
+        time.sleep(1)
+        self.pub.publish(email_msg)
+
+
+if __name__ == '__main__':
+    stm = SmachToMail()
+    rospy.spin()

From 2fe8f2190a883fbc96304619155e5316528db1fd Mon Sep 17 00:00:00 2001
From: Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>
Date: Wed, 27 Jul 2022 12:49:11 +0900
Subject: [PATCH 55/77] add more typecheck, use rospy.loginfo for message

---
 .../scripts/smach_to_mail.py                  | 35 +++++++++++++------
 1 file changed, 24 insertions(+), 11 deletions(-)
 mode change 100644 => 100755 jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
old mode 100644
new mode 100755
index 4a038b4281..86434748bf
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -33,18 +33,27 @@ def _status_cb(self, msg):
         '''
         Recording starts when smach_state becomes start.
         '''
+        rospy.loginfo("Received SMACH status")
         if len(msg.active_states) == 0:
             return
         file_path = None
         status_str = ', '.join(msg.active_states);
         local_data_str = pickle.loads(msg.local_data)
         info_str = msg.info
-        print("status -> {}".format(status_str))
-        print("description_str -> {}".format(local_data_str['DESCRIPTION']))
+        if not type(local_data_str) is dict:
+            rospy.logerr("local_data_str:({}) is not dictionary".format(local_data_str))
+            rospy.logerr("May be you forget to pass user data in exec-state-machine ?")
+            rospy.logerr("please check your program execute smach with (exec-state-machine (sm) '((description . "")(image . "")))")
+
+        rospy.loginfo("- status -> {}".format(status_str))
+        if local_data_str.has_key('DESCRIPTION'):
+            rospy.loginfo("- description_str -> {}".format(local_data_str['DESCRIPTION']))
+        else:
+            rospy.logwarn("smach does not have DESCRIPTION, see https://github.com/jsk-ros-pkg/jsk_robot/tree/master/jsk_robot_common/jsk_robot_startup#smach_to_mailpy for more info")
 
         if status_str == "START" or "INIT":
             self.smach_state_list = []
-        if local_data_str['IMAGE']:
+        if local_data_str.has_key('IMAGE') and local_data_str['IMAGE']:
             imgmsg = CompressedImage()
             imgmsg.deserialize(base64.b64decode(local_data_str['IMAGE']))
             cv_image = self.bridge.compressed_imgmsg_to_cv2(imgmsg, "bgr8")
@@ -54,7 +63,7 @@ def _status_cb(self, msg):
 
             file_path = "/tmp/{}_{}.jpg".format(
                 status_str.lower(), dt_now.strftime('%y%m%d%H%M%S'))
-            rospy.loginfo("filepath:{}".format(file_path))
+            rospy.loginfo("- filepath:{}".format(file_path))
             # if (next((x for x in self.smach_state_list if x["IMAGE"] == file_path), None)):
             #     rospy.loginfo("same file name!!!!")
             # else:
@@ -65,13 +74,16 @@ def _status_cb(self, msg):
         else:
             file_path = ""
 
-        status_dict = {'DESCRIPTION': local_data_str['DESCRIPTION'],
-                       'IMAGE': file_path}  # dict is complicated?
+        status_dict = {}
+        if local_data_str.has_key('DESCRIPTION'):
+            status_dict.update({'DESCRIPTION': local_data_str['DESCRIPTION']})
+        if file_path != "":
+            status_dict.update({'IMAGE': file_path})  # dict is complicated?
+
         self.smach_state_list.append(status_dict)
-        print(self.smach_state_list)
-        print("info_str -> {}".format(info_str))
+        rospy.loginfo("- info_str -> {}".format(info_str))
 
-        if status_str == "END" or "FINISH":
+        if status_str in ["END", "FINISH"]:
             rospy.loginfo("END!!")
             self._send_mail()
 
@@ -85,10 +97,11 @@ def _send_mail(self):
             description = EmailBody()
             image = EmailBody()
             description.type = 'text'
-            description.message = x['DESCRIPTION']
+            if x.has_key('DESCRIPTION'):
+                description.message = x['DESCRIPTION']
             email_msg.body.append(description)
             email_msg.body.append(changeline)
-            if x['IMAGE']:
+            if x.has_key('IMAGE') and x['IMAGE']:
                 image.type = 'img'
                 image.img_size = 50
                 image.file_path = x['IMAGE']

From d4f0597171ce3ceee97dd30adf404545a35fc85a Mon Sep 17 00:00:00 2001
From: Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>
Date: Wed, 27 Jul 2022 22:19:31 +0900
Subject: [PATCH 56/77] use https://github.com/tkmtnt7000/jsk_robot/pull/5 to
 publish image string, not file, set image resolution to 640, use DESCRIPTION
 of START node as mail subject, warn if we received status without START node

---
 .../scripts/smach_to_mail.py                  | 85 ++++++++++---------
 1 file changed, 47 insertions(+), 38 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index 86434748bf..22795b95b1 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -25,7 +25,7 @@ def __init__(self):
         rospy.Subscriber(
             "~smach/container_status", SmachContainerStatus, self._status_cb)
         self.bridge = CvBridge()
-        self.smach_state_list = []  # for status list
+        self.smach_state_list = None  # for status list
         self.sender_address = "tsukamoto@jsk.imi.i.u-tokyo.ac.jp"
         self.receiver_address = "tsukamoto@jsk.imi.i.u-tokyo.ac.jp"
 
@@ -46,46 +46,51 @@ def _status_cb(self, msg):
             rospy.logerr("please check your program execute smach with (exec-state-machine (sm) '((description . "")(image . "")))")
 
         rospy.loginfo("- status -> {}".format(status_str))
+        rospy.loginfo("- info_str -> {}".format(info_str))
         if local_data_str.has_key('DESCRIPTION'):
             rospy.loginfo("- description_str -> {}".format(local_data_str['DESCRIPTION']))
         else:
             rospy.logwarn("smach does not have DESCRIPTION, see https://github.com/jsk-ros-pkg/jsk_robot/tree/master/jsk_robot_common/jsk_robot_startup#smach_to_mailpy for more info")
+        if local_data_str.has_key('IMAGE') and local_data_str['IMAGE']:
+            rospy.loginfo("- image_str -> {}".format(local_data_str['IMAGE'][:64]))
 
-        if status_str == "START" or "INIT":
+        if status_str in ["START", "INIT"]:
             self.smach_state_list = []
-        if local_data_str.has_key('IMAGE') and local_data_str['IMAGE']:
-            imgmsg = CompressedImage()
-            imgmsg.deserialize(base64.b64decode(local_data_str['IMAGE']))
-            cv_image = self.bridge.compressed_imgmsg_to_cv2(imgmsg, "bgr8")
-            rospy.logerr(
-                "cv image type:{}".format(imghdr.what(None, cv_image)))  # for debugging
-            dt_now = datetime.datetime.now()   # header should be used??
-
-            file_path = "/tmp/{}_{}.jpg".format(
-                status_str.lower(), dt_now.strftime('%y%m%d%H%M%S'))
-            rospy.loginfo("- filepath:{}".format(file_path))
-            # if (next((x for x in self.smach_state_list if x["IMAGE"] == file_path), None)):
-            #     rospy.loginfo("same file name!!!!")
-            # else:
-            #     rospy.loginfo("not same file name!!!")
-            cv2.imwrite(file_path, cv_image)
-            # cv2.imshow("Image", input_image)
-            cv2.waitKey(2)
-        else:
-            file_path = ""
+            # DESCRIPTION of START is MAIL SUBJECT
+            if local_data_str.has_key('DESCRIPTION'):
+                self.smach_state_subject = local_data_str['DESCRIPTION']
+                del local_data_str['DESCRIPTION']
+            else:
+                self.smach_state_subject = None
 
         status_dict = {}
         if local_data_str.has_key('DESCRIPTION'):
             status_dict.update({'DESCRIPTION': local_data_str['DESCRIPTION']})
-        if file_path != "":
-            status_dict.update({'IMAGE': file_path})  # dict is complicated?
 
-        self.smach_state_list.append(status_dict)
-        rospy.loginfo("- info_str -> {}".format(info_str))
+        if local_data_str.has_key('IMAGE') and local_data_str['IMAGE']:
+            imgmsg = CompressedImage()
+            imgmsg.deserialize(base64.b64decode(local_data_str['IMAGE']))
+            cv_image = self.bridge.compressed_imgmsg_to_cv2(imgmsg, "bgr8")
+            scale_percent = 640.0 / cv_image.shape[1] * 100.0
+            width = int(cv_image.shape[1] * scale_percent / 100)
+            height = int(cv_image.shape[0] * scale_percent / 100)
+            dim = (width, height)
+            cv_image = cv2.resize(cv_image, dim, interpolation = cv2.INTER_AREA)
+            status_dict.update({'IMAGE': base64.b64encode(cv2.imencode('.jpg', cv_image)[1].tostring())})  # dict is complicated?
+
+        if self.smach_state_list == None:
+            rospy.logwarn("received {}, but we did not find START node".format(status_dict))
+        else:
+            self.smach_state_list.append(status_dict)
 
         if status_str in ["END", "FINISH"]:
-            rospy.loginfo("END!!")
-            self._send_mail()
+            if self.smach_state_list == None:
+                rospy.logwarn("received END node, but we did not find START node")
+                rospy.logwarn("failed to send {}".format(status_dict))
+            else:
+                rospy.loginfo("END!!")
+                self._send_mail()
+                self.smach_state_list = None
 
     def _send_mail(self):
         email_msg = Email()
@@ -94,27 +99,31 @@ def _send_mail(self):
         changeline.type = 'html'
         changeline.message = "<br>"
         for x in self.smach_state_list:
-            description = EmailBody()
-            image = EmailBody()
-            description.type = 'text'
             if x.has_key('DESCRIPTION'):
+                description = EmailBody()
+                description.type = 'text'
                 description.message = x['DESCRIPTION']
-            email_msg.body.append(description)
-            email_msg.body.append(changeline)
+                email_msg.body.append(description)
+                email_msg.body.append(changeline)
             if x.has_key('IMAGE') and x['IMAGE']:
+                image = EmailBody()
                 image.type = 'img'
-                image.img_size = 50
-                image.file_path = x['IMAGE']
+                image.img_size = 100
+                image.img_data = x['IMAGE']
                 email_msg.body.append(image)
                 email_msg.body.append(changeline)
-        rospy.loginfo("body:{}".format(email_msg.body))
+        # rospy.loginfo("body:{}".format(email_msg.body))
 
-        email_msg.subject = 'Smach mail test'
+        if self.smach_state_subject:
+            email_msg.subject = self.smach_state_subject
+        else:
+            email_msg.subject = 'Message from {}'.format(rospy.get_param('/robot/name', 'robot'))
 
         email_msg.sender_address = self.sender_address
         email_msg.receiver_address = self.receiver_address
 
-        time.sleep(1)
+        rospy.loginfo("send '{}' email to {}".format(email_msg.subject, email_msg.receiver_address))
+
         self.pub.publish(email_msg)
 
 

From cc1777f3b371c2ea80b5fbe86b9310b434c3cc18 Mon Sep 17 00:00:00 2001
From: Kei Okada <kei.okada@gmail.com>
Date: Tue, 9 Aug 2022 11:51:33 +0900
Subject: [PATCH 57/77] enable to receive multiple smach state

---
 .../scripts/smach_to_mail.py                  | 46 +++++++++++++------
 1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index 22795b95b1..9ef2338b59 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -25,7 +25,8 @@ def __init__(self):
         rospy.Subscriber(
             "~smach/container_status", SmachContainerStatus, self._status_cb)
         self.bridge = CvBridge()
-        self.smach_state_list = None  # for status list
+        self.smach_state_list = {}  # for status list
+        self.smach_state_subject = {}  # for status subject
         self.sender_address = "tsukamoto@jsk.imi.i.u-tokyo.ac.jp"
         self.receiver_address = "tsukamoto@jsk.imi.i.u-tokyo.ac.jp"
 
@@ -36,7 +37,8 @@ def _status_cb(self, msg):
         rospy.loginfo("Received SMACH status")
         if len(msg.active_states) == 0:
             return
-        file_path = None
+
+        # Print received messages
         status_str = ', '.join(msg.active_states);
         local_data_str = pickle.loads(msg.local_data)
         info_str = msg.info
@@ -54,15 +56,21 @@ def _status_cb(self, msg):
         if local_data_str.has_key('IMAGE') and local_data_str['IMAGE']:
             rospy.loginfo("- image_str -> {}".format(local_data_str['IMAGE'][:64]))
 
+        # Store data for every callerid to self.smach_state_list[caller_id]
+        caller_id = msg._connection_header['callerid']
+
+        # If we received START/INIT status, restart storing smach_state_list
         if status_str in ["START", "INIT"]:
-            self.smach_state_list = []
+            self.smach_state_list[caller_id] = []
             # DESCRIPTION of START is MAIL SUBJECT
             if local_data_str.has_key('DESCRIPTION'):
-                self.smach_state_subject = local_data_str['DESCRIPTION']
+                self.smach_state_subject[caller_id] = local_data_str['DESCRIPTION']
                 del local_data_str['DESCRIPTION']
             else:
-                self.smach_state_subject = None
+                self.smach_state_subject[celler_id] = None
 
+        # Build status_dict for every status
+        # expected keys are 'DESCRIPTION' , 'IMAGE', 'STATE', 'INFO', 'TIME'
         status_dict = {}
         if local_data_str.has_key('DESCRIPTION'):
             status_dict.update({'DESCRIPTION': local_data_str['DESCRIPTION']})
@@ -77,28 +85,36 @@ def _status_cb(self, msg):
             dim = (width, height)
             cv_image = cv2.resize(cv_image, dim, interpolation = cv2.INTER_AREA)
             status_dict.update({'IMAGE': base64.b64encode(cv2.imencode('.jpg', cv_image)[1].tostring())})  # dict is complicated?
+        status_dict.update({'STATE': status_str})
+        status_dict.update({'INFO': info_str})
+        status_dict.update({'TIME': datetime.datetime.fromtimestamp(msg.header.stamp.to_sec())})
 
-        if self.smach_state_list == None:
+        if ( not self.smach_state_list.has_key(caller_id) ) or self.smach_state_list[caller_id] == None:
             rospy.logwarn("received {}, but we did not find START node".format(status_dict))
         else:
-            self.smach_state_list.append(status_dict)
+            self.smach_state_list[caller_id].append(status_dict)
 
+        # If we received END/FINISH status, send email, etc...
         if status_str in ["END", "FINISH"]:
-            if self.smach_state_list == None:
+            if ( not self.smach_state_list.has_key(caller_id) ) or self.smach_state_list[caller_id] == None:
                 rospy.logwarn("received END node, but we did not find START node")
                 rospy.logwarn("failed to send {}".format(status_dict))
             else:
                 rospy.loginfo("END!!")
-                self._send_mail()
-                self.smach_state_list = None
-
-    def _send_mail(self):
+                rospy.loginfo("Following SMACH is reported")
+                for x in self.smach_state_list[caller_id]:
+                    rospy.loginfo(" - At {}, Active state is {}{}".format(x['TIME'], x['STATE'],
+                                  "({})".format(x['INFO']) if x['INFO'] else ''))
+                self._send_mail(self.smach_state_subject[caller_id], self.smach_state_list[caller_id])
+                self.smach_state_list[caller_id] = None
+
+    def _send_mail(self, subject, state_list):
         email_msg = Email()
         email_msg.body = []
         changeline = EmailBody()
         changeline.type = 'html'
         changeline.message = "<br>"
-        for x in self.smach_state_list:
+        for x in state_list:
             if x.has_key('DESCRIPTION'):
                 description = EmailBody()
                 description.type = 'text'
@@ -114,8 +130,8 @@ def _send_mail(self):
                 email_msg.body.append(changeline)
         # rospy.loginfo("body:{}".format(email_msg.body))
 
-        if self.smach_state_subject:
-            email_msg.subject = self.smach_state_subject
+        if subject:
+            email_msg.subject = subject
         else:
             email_msg.subject = 'Message from {}'.format(rospy.get_param('/robot/name', 'robot'))
 

From 0dd909e84e7ab731e9b36d4629600b1a8cf78577 Mon Sep 17 00:00:00 2001
From: Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>
Date: Tue, 9 Aug 2022 16:21:18 +0900
Subject: [PATCH 58/77] add to pubilsh /tweet message

---
 .../scripts/smach_to_mail.py                  | 22 +++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index 9ef2338b59..bde3899494 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -13,6 +13,7 @@
 from jsk_robot_startup.msg import EmailBody
 from sensor_msgs.msg import CompressedImage
 from smach_msgs.msg import SmachContainerStatus
+from std_msgs.msg import String
 
 
 class SmachToMail():
@@ -21,7 +22,8 @@ def __init__(self):
         rospy.init_node('server_name')
         # it should be 'smach_to_mail', but 'server_name'
         # is the default name of smach_ros
-        self.pub = rospy.Publisher("/email", Email, queue_size=10)
+        self.pub_email = rospy.Publisher("email", Email, queue_size=10)
+        self.pub_twitter = rospy.Publisher("tweet", String, queue_size=10)
         rospy.Subscriber(
             "~smach/container_status", SmachContainerStatus, self._status_cb)
         self.bridge = CvBridge()
@@ -106,6 +108,7 @@ def _status_cb(self, msg):
                     rospy.loginfo(" - At {}, Active state is {}{}".format(x['TIME'], x['STATE'],
                                   "({})".format(x['INFO']) if x['INFO'] else ''))
                 self._send_mail(self.smach_state_subject[caller_id], self.smach_state_list[caller_id])
+                self._send_twitter(self.smach_state_subject[caller_id], self.smach_state_list[caller_id])
                 self.smach_state_list[caller_id] = None
 
     def _send_mail(self, subject, state_list):
@@ -140,7 +143,22 @@ def _send_mail(self, subject, state_list):
 
         rospy.loginfo("send '{}' email to {}".format(email_msg.subject, email_msg.receiver_address))
 
-        self.pub.publish(email_msg)
+        self.pub_email.publish(email_msg)
+
+    def _send_twitter(self, subject, state_list):
+        if subject:
+            self.pub_twitter.publish(String(subject))
+            rospy.loginfo("send '{}' to twitter".format(subject))
+
+        for x in state_list:
+            text = ""
+            if x.has_key('DESCRIPTION'):
+                text = x['DESCRIPTION']
+            if x.has_key('IMAGE') and x['IMAGE']:
+                text += x['IMAGE']
+            if len(text) > 1:
+                self.pub_twitter.publish(String(text))
+                rospy.loginfo("send '{}' to twitter".format(text[0:144]))
 
 
 if __name__ == '__main__':

From 0bfbf7901fe9025d7f2755850b22da4b4766f4f2 Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Thu, 28 Jul 2022 13:09:15 +0900
Subject: [PATCH 59/77] [jsk_robot_startup] Fix dependent on linter

---
 .../scripts/smach_to_mail.py                  | 31 +++++++++++--------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index bde3899494..b81d5a4ad4 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -41,8 +41,12 @@ def _status_cb(self, msg):
             return
 
         # Print received messages
-        status_str = ', '.join(msg.active_states);
-        local_data_str = pickle.loads(msg.local_data)
+        status_str = ', '.join(msg.active_states)
+        if sys.version_info.major < 3:
+            local_data_str = pickle.loads(msg.local_data)
+        else:
+            local_data_str = pickle.loads(
+                msg.local_data.encode('utf-8'), encoding='utf-8')
         info_str = msg.info
         if not type(local_data_str) is dict:
             rospy.logerr("local_data_str:({}) is not dictionary".format(local_data_str))
@@ -51,11 +55,11 @@ def _status_cb(self, msg):
 
         rospy.loginfo("- status -> {}".format(status_str))
         rospy.loginfo("- info_str -> {}".format(info_str))
-        if local_data_str.has_key('DESCRIPTION'):
+        if 'DESCRIPTION' in local_data_str:
             rospy.loginfo("- description_str -> {}".format(local_data_str['DESCRIPTION']))
         else:
             rospy.logwarn("smach does not have DESCRIPTION, see https://github.com/jsk-ros-pkg/jsk_robot/tree/master/jsk_robot_common/jsk_robot_startup#smach_to_mailpy for more info")
-        if local_data_str.has_key('IMAGE') and local_data_str['IMAGE']:
+        if 'IMAGE' in local_data_str and local_data_str['IMAGE']:
             rospy.loginfo("- image_str -> {}".format(local_data_str['IMAGE'][:64]))
 
         # Store data for every callerid to self.smach_state_list[caller_id]
@@ -65,7 +69,7 @@ def _status_cb(self, msg):
         if status_str in ["START", "INIT"]:
             self.smach_state_list[caller_id] = []
             # DESCRIPTION of START is MAIL SUBJECT
-            if local_data_str.has_key('DESCRIPTION'):
+            if 'DESCRIPTION' in local_data_str:
                 self.smach_state_subject[caller_id] = local_data_str['DESCRIPTION']
                 del local_data_str['DESCRIPTION']
             else:
@@ -74,10 +78,10 @@ def _status_cb(self, msg):
         # Build status_dict for every status
         # expected keys are 'DESCRIPTION' , 'IMAGE', 'STATE', 'INFO', 'TIME'
         status_dict = {}
-        if local_data_str.has_key('DESCRIPTION'):
+        if 'DESCRIPTION' in local_data_str:
             status_dict.update({'DESCRIPTION': local_data_str['DESCRIPTION']})
 
-        if local_data_str.has_key('IMAGE') and local_data_str['IMAGE']:
+        if 'IMAGE' in local_data_str and local_data_str['IMAGE']:
             imgmsg = CompressedImage()
             imgmsg.deserialize(base64.b64decode(local_data_str['IMAGE']))
             cv_image = self.bridge.compressed_imgmsg_to_cv2(imgmsg, "bgr8")
@@ -91,14 +95,15 @@ def _status_cb(self, msg):
         status_dict.update({'INFO': info_str})
         status_dict.update({'TIME': datetime.datetime.fromtimestamp(msg.header.stamp.to_sec())})
 
-        if ( not self.smach_state_list.has_key(caller_id) ) or self.smach_state_list[caller_id] == None:
+
+        if (caller_id not in self.smach_state_list) or self.smach_state_list[caller_id] is None:
             rospy.logwarn("received {}, but we did not find START node".format(status_dict))
         else:
             self.smach_state_list[caller_id].append(status_dict)
 
         # If we received END/FINISH status, send email, etc...
         if status_str in ["END", "FINISH"]:
-            if ( not self.smach_state_list.has_key(caller_id) ) or self.smach_state_list[caller_id] == None:
+            if (caller_id not in self.smach_state_list) or self.smach_state_list[caller_id] is None:
                 rospy.logwarn("received END node, but we did not find START node")
                 rospy.logwarn("failed to send {}".format(status_dict))
             else:
@@ -118,13 +123,13 @@ def _send_mail(self, subject, state_list):
         changeline.type = 'html'
         changeline.message = "<br>"
         for x in state_list:
-            if x.has_key('DESCRIPTION'):
+            if 'DESCRIPTION' in x:
                 description = EmailBody()
                 description.type = 'text'
                 description.message = x['DESCRIPTION']
                 email_msg.body.append(description)
                 email_msg.body.append(changeline)
-            if x.has_key('IMAGE') and x['IMAGE']:
+            if 'IMAGE' in x and x['IMAGE']:
                 image = EmailBody()
                 image.type = 'img'
                 image.img_size = 100
@@ -152,9 +157,9 @@ def _send_twitter(self, subject, state_list):
 
         for x in state_list:
             text = ""
-            if x.has_key('DESCRIPTION'):
+            if 'DESCRIPTION' in x:
                 text = x['DESCRIPTION']
-            if x.has_key('IMAGE') and x['IMAGE']:
+            if 'IMAGE' in x and x['IMAGE']:
                 text += x['IMAGE']
             if len(text) > 1:
                 self.pub_twitter.publish(String(text))

From 7d1958ed30c44b2341e0d1b5842b6b0aa0ad9c84 Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Thu, 28 Jul 2022 18:53:52 +0900
Subject: [PATCH 60/77] [jsk_robot_startup] Support python3 in smach_to_mail.py

---
 jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index b81d5a4ad4..b28a7be6c5 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -7,6 +7,7 @@
 import pickle
 import rospy
 import time
+import sys
 
 from cv_bridge import CvBridge
 from jsk_robot_startup.msg import Email

From a935e96b922a0d62f23b6b4d31ce20a3f39ee44a Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Tue, 9 Aug 2022 23:24:14 +0900
Subject: [PATCH 61/77] [jsk_robot_startup/smach_mail] Fix typo

---
 jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index b28a7be6c5..6bbd550dbf 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -74,7 +74,7 @@ def _status_cb(self, msg):
                 self.smach_state_subject[caller_id] = local_data_str['DESCRIPTION']
                 del local_data_str['DESCRIPTION']
             else:
-                self.smach_state_subject[celler_id] = None
+                self.smach_state_subject[caller_id] = None
 
         # Build status_dict for every status
         # expected keys are 'DESCRIPTION' , 'IMAGE', 'STATE', 'INFO', 'TIME'

From f3933dd9650f691cab63927058e19b897e940bf4 Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Tue, 9 Aug 2022 23:25:10 +0900
Subject: [PATCH 62/77] [jsk_robot_startup/smach_mail] Remove unused module

---
 jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py | 2 --
 1 file changed, 2 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index 6bbd550dbf..8033afef74 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -3,10 +3,8 @@
 import base64
 import cv2
 import datetime
-import imghdr
 import pickle
 import rospy
-import time
 import sys
 
 from cv_bridge import CvBridge

From 3d41642dae1045afc5fc0d5dfd0e87bf79d212db Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Tue, 9 Aug 2022 23:30:05 +0900
Subject: [PATCH 63/77] [jsk_robot_startup/smach_to_mail] Set sender address
 and receiver address from rosparam

---
 jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index 8033afef74..15642bb4f8 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -28,8 +28,8 @@ def __init__(self):
         self.bridge = CvBridge()
         self.smach_state_list = {}  # for status list
         self.smach_state_subject = {}  # for status subject
-        self.sender_address = "tsukamoto@jsk.imi.i.u-tokyo.ac.jp"
-        self.receiver_address = "tsukamoto@jsk.imi.i.u-tokyo.ac.jp"
+        self.sender_address = rospy.get_param("~sender_address")
+        self.receiver_address = rospy.get_param("~receiver_address")
 
     def _status_cb(self, msg):
         '''

From 2542efdbbaa3e5ac1d3ffd229a84187616ae19fc Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Mon, 22 Aug 2022 10:31:25 +0900
Subject: [PATCH 64/77] [jsk_robot_startup/smach_to_mail] Raise error when no
 address is set

---
 .../jsk_robot_startup/scripts/smach_to_mail.py      | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index 15642bb4f8..fff6597cd2 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -28,8 +28,17 @@ def __init__(self):
         self.bridge = CvBridge()
         self.smach_state_list = {}  # for status list
         self.smach_state_subject = {}  # for status subject
-        self.sender_address = rospy.get_param("~sender_address")
-        self.receiver_address = rospy.get_param("~receiver_address")
+        if rospy.has_param("~sender_address"):
+            self.sender_address = rospy.get_param("~sender_address")
+        else:
+            rospy.logerr("Please set rosparam {}/sender_address".format(
+                rospy.get_name()))
+        if rospy.has_param("~receiver_address"):
+            self.receiver_address = rospy.get_param("~receiver_address")
+        else:
+            rospy.logerr("Please set rosparam {}/receiver_address".format(
+                    rospy.get_name()))
+
 
     def _status_cb(self, msg):
         '''

From 10757570bca8be56f6585227844f4877723f0677 Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Mon, 22 Aug 2022 15:37:02 +0900
Subject: [PATCH 65/77] [jsk_robot_startup/smach_to_mail] Use yaml file to set
 address

---
 .../scripts/smach_to_mail.py                  | 29 ++++++++++++++-----
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index fff6597cd2..c49d73cc32 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -3,9 +3,11 @@
 import base64
 import cv2
 import datetime
+import os
 import pickle
 import rospy
 import sys
+import yaml
 
 from cv_bridge import CvBridge
 from jsk_robot_startup.msg import Email
@@ -28,16 +30,27 @@ def __init__(self):
         self.bridge = CvBridge()
         self.smach_state_list = {}  # for status list
         self.smach_state_subject = {}  # for status subject
-        if rospy.has_param("~sender_address"):
-            self.sender_address = rospy.get_param("~sender_address")
+        yaml_path = rospy.get_param(
+            '~email_info', "/var/lib/robot/email_info.yaml")
+        if os.path.exists(yaml_path):
+            with open(yaml_path) as yaml_f:
+                self.email_info = yaml.load(yaml_f)
+            rospy.loginfo(
+                "{} is loaded as email config file.".format(yaml_path))
+            rospy.loginfo(self.email_info)
+            self.sender_address = self.email_info['sender_address']
+            self.receiver_address = self.email_info['receiver_address']
         else:
-            rospy.logerr("Please set rosparam {}/sender_address".format(
-                rospy.get_name()))
-        if rospy.has_param("~receiver_address"):
-            self.receiver_address = rospy.get_param("~receiver_address")
-        else:
-            rospy.logerr("Please set rosparam {}/receiver_address".format(
+            if rospy.has_param("~sender_address"):
+                self.sender_address = rospy.get_param("~sender_address")
+            else:
+                rospy.logerr("Please set rosparam {}/sender_address".format(
                     rospy.get_name()))
+            if rospy.has_param("~receiver_address"):
+                self.receiver_address = rospy.get_param("~receiver_address")
+            else:
+                rospy.logerr("Please set rosparam {}/receiver_address".format(
+                        rospy.get_name()))
 
 
     def _status_cb(self, msg):

From 54a3d1a7a1a404524aa1d4fbc3183cb00fbd812b Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 22 Aug 2022 17:37:50 +0900
Subject: [PATCH 66/77] [jsk_robot_startup] Publish whole /tweet at a time

---
 .../scripts/smach_to_mail.py                  | 20 +++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
index c49d73cc32..33b7f8eac6 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/smach_to_mail.py
@@ -172,19 +172,19 @@ def _send_mail(self, subject, state_list):
         self.pub_email.publish(email_msg)
 
     def _send_twitter(self, subject, state_list):
+        text = ""
         if subject:
-            self.pub_twitter.publish(String(subject))
-            rospy.loginfo("send '{}' to twitter".format(subject))
-
+            text += subject
         for x in state_list:
-            text = ""
-            if 'DESCRIPTION' in x:
-                text = x['DESCRIPTION']
+            if 'DESCRIPTION' in x and x['DESCRIPTION']:
+                text += '\n' + x['DESCRIPTION']
             if 'IMAGE' in x and x['IMAGE']:
-                text += x['IMAGE']
-            if len(text) > 1:
-                self.pub_twitter.publish(String(text))
-                rospy.loginfo("send '{}' to twitter".format(text[0:144]))
+                img_txt = x['IMAGE']
+                if isinstance(img_txt, bytes):
+                    img_txt = img_txt.decode('ascii')
+                text += img_txt
+        if len(text) > 1:
+            self.pub_twitter.publish(String(text))
 
 
 if __name__ == '__main__':

From 7a4f0186f197b940c609c0574fdd071d3ca186a5 Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Tue, 23 Aug 2022 14:42:08 +0900
Subject: [PATCH 67/77] [jsk_robot_startup] Add Readme for smach_to_mail.py

---
 jsk_robot_common/jsk_robot_startup/README.md | 53 ++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/jsk_robot_common/jsk_robot_startup/README.md b/jsk_robot_common/jsk_robot_startup/README.md
index ce43e215a6..5544d7016e 100644
--- a/jsk_robot_common/jsk_robot_startup/README.md
+++ b/jsk_robot_common/jsk_robot_startup/README.md
@@ -209,6 +209,59 @@ rostopic pub /reboot std_msgs/Empty
 ```
 
 
+## scripts/smach_to_mail.py
+
+This node sends smach messages to `/email`, `/tweet`, etc... to notify robot state transition.
+
+```mermaid
+flowchart TB
+    subgraph S[Demo Code Running on SMACH]
+      START --> State_1
+      State_1 --> State_2
+      State_2 --> END
+    end
+   subgraph E[SMACH To Notification]
+      id1[(state list<br>DESCRIPTION / IMAGE<br>DESCRIPTION / IMAGE<br>...)]
+     id1 --> email[[pub /email jsk_robot_startup::Email]]
+     id1 --> tweet[[pub /tweet std_msgs::String]] 
+     id1 --> chat[[pub /google_chat_ros/send/goal<br>google_chat_ros::SendMessageAction]] 
+   end
+   S -->|"[{'DESCRIPTION': string, 'IMAGE': base64}]"| E
+   email --> email_body(["DESCRIPTION[0]<br>DESCRIPTION[1]<br>IMAGE[1]<br>DESCRIPTION[1]<br>IMAGE[1]<br>..."])
+   tweet --> tweet_body1(["DESCRIPTION[0]"])
+   tweet_body1 --> tweet_body2(["DESCRIPTION[1]<br>IMAGE[1]"])
+   tweet_body2 --> tweet_body3(["DESCRIPTION[2]<br>IMAGE[2]"])
+   chat --> chat_body1(["DESCRIPTION[0]"])
+   chat_body1 --> chat_body2(["DESCRIPTION[1]<br>IMAGE[1]"])
+   chat_body2 --> chat_body3(["DESCRIPTION[2]<br>IMAGE[2]"])
+```
+
+### Subscribing Topics
+
+* `~smach/container_status` (`smach_msgs/SmachContainerStatus`)
+
+  Input topic smach status
+
+### Publishing Topics
+
+* `/email` (`jsk_robot_startup/Email`)
+
+  Email message with description and image
+
+* `/tweet` (`std_msgs/String`)
+
+  Tweet message with description and image
+
+### Parameters
+
+* `~sender_address` (String)
+  
+  Sender address
+
+* `~receiver_address` (String)
+
+  Receiver address
+
 ## launch/safe_teleop.launch
 
 This launch file provides a set of nodes for safe teleoperation common to mobile robots. Robot-specific nodes such as `/joy`, `/teleop` or `/cable_warning` must be included in the teleop launch file for each robot, such as [safe_teleop.xml for PR2](https://github.com/jsk-ros-pkg/jsk_robot/blob/master/jsk_pr2_robot/jsk_pr2_startup/jsk_pr2_move_base/safe_teleop.xml) or [safe_teleop.xml for fetch](https://github.com/jsk-ros-pkg/jsk_robot/blob/master/jsk_fetch_robot/jsk_fetch_startup/launch/fetch_teleop.xml).

From cfdfc6e52a781f6acc896e7e5ce985566ce3b26d Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 29 Aug 2022 15:21:28 +0900
Subject: [PATCH 68/77] Revert "[jsk_unitree_startup] Launch trt pose on jetson
 nano2gb (192.168.123.13)"

This reverts commit 8d9eb4a462e34bd62732f70f49e5c2cf1d22f8bd.
---
 jsk_unitree_robot/cross/install.sh              | 14 +++-----------
 .../jsk_unitree_startup/autostart/imageai.sh    |  3 +--
 .../scripts/publish_human_pose.diff             | 17 +----------------
 3 files changed, 5 insertions(+), 29 deletions(-)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index 767bb10b03..fce1d02c5f 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -137,7 +137,6 @@ function copy_data () {
 
 if [[ ${TYPE} == "Pro" ]] ; then
     copy_data pi 192.168.123.161
-    copy_data unitree 192.168.123.13
     copy_data unitree 192.168.123.14
     ## copy_data unitree 192.168.123.15 : Pro : No Space for auto start
 elif [[ ${TYPE} == "Air" ]] ; then
@@ -148,10 +147,8 @@ else
 fi
 
 if [[ "${TARGET_DIRECTORY}" == "User" ]]; then
-    cuda_ip="192.168.123.13"
     if [[ ${TYPE} == "Pro" ]] ; then
-        sshpass -p 123 scp ${TARGET_MACHINE}_${TARGET_DIRECTORY}/src/jsk_robot/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh unitree@192.168.123.13:/home/unitree/Unitree/autostart/imageai/imageai.sh
-        sshpass -p 123 scp ${TARGET_MACHINE}_${TARGET_DIRECTORY}/src/jsk_robot/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh unitree@192.168.123.15:/home/unitree/Unitree/autostart/imageai/imageai.sh
+        cuda_ip="192.168.123.15"
     elif [[ ${TYPE} == "Air" ]] ; then
         cuda_ip="192.168.123.13"
     fi
@@ -163,13 +160,8 @@ if [[ "${TARGET_DIRECTORY}" == "User" ]]; then
     sshpass -p 123 scp ${TARGET_MACHINE}_${TARGET_DIRECTORY}/src/jsk_robot/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff unitree@${cuda_ip}:/tmp/publish_human_pose.diff
     sshpass -p 123 ssh -t unitree@${cuda_ip} bash -c 'ls; OUT="$(patch -p0 --backup --forward /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/pyScripts/live_human_pose.py < /tmp/publish_human_pose.diff | tee /dev/tty)" || echo "${OUT}" | grep "Skipping patch" -q || (echo "$OUT" && false);'
 
-    # launch live_human_pose.py on jetson nano (192.168.123.13)
-    sshpass -p 123 ssh -t unitree@${cuda_ip} "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/pyScripts/live_human_pose.py"
-    # replace 192.168.123.15 -> 192.168.123.13 because live_human_pose.py is running on jetson nano (192.168.123.13)
-    if [[ ${TYPE} == "Pro" ]] ; then
-        sshpass -p 123 ssh -t unitree@192.168.123.13 "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/config/mqSNNRConfig.yaml"
-        sshpass -p 123 ssh -t unitree@192.168.123.14 "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/config/mqSNNLConfig.yaml"
-        sshpass -p 123 ssh -t unitree@192.168.123.15 "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/config/mqMNConfig.yaml"
+    if [[ ${TYPE} == "Air" ]] ; then
+        sshpass -p 123 ssh -t unitree@${cuda_ip} "sed -i 's/192.168.123.15/192.168.123.13/g' /home/unitree/Unitree/autostart/imageai/mLComSystemFrame/pyScripts/live_human_pose.py"
     fi
 fi
 
diff --git a/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh b/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
index 6f98fd581b..6401998441 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
+++ b/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
@@ -52,7 +52,7 @@ if [ $localIPAddr == $Nano3 ];then
 	echo "	MasterNano"
 	############### MasterNano doing things!!!!
 	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqMNConfig.yaml; exec bash"
-	# gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/pyScripts; python3 live_human_pose.py; exec bash"
+	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/pyScripts; python3 live_human_pose.py; exec bash"
 
 elif [ $localIPAddr == $Nano2 ];then
 	echo "	SecNanoLeft"
@@ -65,7 +65,6 @@ elif [ $localIPAddr == $Nano1 ];then
 	############### SecNanoRight(1-2) doing things!!!!
 	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNRConfig.yaml; exec bash"
 	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNRConfig.yaml 1; exec bash"
-  gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/pyScripts; python3 live_human_pose.py; exec bash"
 else
 	echo "	Not Found $localIPAddr in IP-Clump!"
 fi
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff b/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff
index cfae1f90d7..960c221f2f 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff
@@ -1,12 +1,6 @@
 --- live_human_pose.py	2022-05-26 00:17:04.634784206 +0900
 +++ live_human_pose_jsk.py	2022-05-26 00:17:18.102931810 +0900
-@@ -1,4 +1,5 @@
- #coding:utf-8
-+import base64
- import json
- import trt_pose . coco
- import trt_pose . models
-@@ -169,6 +171,8 @@
+@@ -169,6 +169,8 @@
      if 39 - 39: o00ooo0 - II111iiii * OoO0O00 % o0oOOo0O0Ooo * II111iiii % II111iiii
      cv2 . circle ( src , ( i1I1iI , o0O ) , 8 , I1i1I1II , - 1 )
   iI1Ii11111iIi . write ( src )
@@ -15,12 +9,3 @@
  # cv2 . imshow ( "ai" , src )
  # cv2 . waitKey ( 1 )
   if 59 - 59: iIii1I11I1II1 + I1IiiI - o0oOOo0O0Ooo - I1IiiI + Oo / I1ii11iIi11i
-@@ -199,6 +203,8 @@
-  print ( "AI is working ...." , camIndex . value )
-  Oo0oOOo , Oo0OoO00oOO0o = o0OOO [ camIndex . value - 1 ] . read ( )
-  OOO00O = time . time ( )
-+ # add by iory 2022.8.6
-+ O0ii1ii1ii.publish("vision/front_camera", base64.b64encode(cv2.imencode('.jpg', Oo0OoO00oOO0o, [int(cv2.IMWRITE_JPEG_QUALITY), 90])[1]).decode('ascii'))
-  OOoOO0oo0ooO = cv2 . resize ( Oo0OoO00oOO0o , dsize = ( OooO0 , II11iiii1Ii ) , interpolation = cv2 . INTER_AREA )
-  iI ( OOoOO0oo0ooO , Oo0OoO00oOO0o , OOO00O )
-  if 98 - 98: I1II1 * I1II1 / I1II1 + O00ooOO

From eb02f63649d661bc212adbf59261b4d631868ce3 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 29 Aug 2022 15:21:32 +0900
Subject: [PATCH 69/77] Revert "[jsk_unitree_startup] Add imageai.sh which is
 running on default unitree pro"

This reverts commit f8e3778dbe0ae069009adc75ef77571720b73953.
---
 .../jsk_unitree_startup/autostart/imageai.sh  | 72 -------------------
 1 file changed, 72 deletions(-)
 delete mode 100755 jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh

diff --git a/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh b/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
deleted file mode 100755
index 6401998441..0000000000
--- a/jsk_unitree_robot/jsk_unitree_startup/autostart/imageai.sh
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/bin/bash
-Nano1="192.168.123.13"  ## SecNanoRight(1-2)
-Nano2="192.168.123.14"	## SecNanoLeft(3-4)
-Nano3="192.168.123.15"	## MasterNano(5)
-eval echo "[imageai] starting ... " $toStartlog
-
-mLRootPATH="/home/unitree/Unitree/autostart/imageai/"
-updatePackagePATH="/home/unitree/mLComSystemFrame.tar.gz"
-
-echo -e "\e[1;32m**** 1. Check if the program needs to be updated ? ****\e[0m"
-checkIFUpdate(){
-	if [ -f "$updatePackagePATH" ];then
-		echo -e "\e[1;32m	The update file exists, it will be updating soon ...\e[0m"
-		tar -zxvf $updatePackagePATH -C $mLRootPATH > /dev/null; sleep 1
-		rm -rf $updatePackagePATH
-		echo -e "\e[1;32m	Updating Success.\e[0m"
-	else
-		echo -e "\e[1;31m	NO Need to update!\e[0m"
-	fi
-}
-
-checkIFUpdate
-# dd=$?
-
-#declare -i lossNano1=-1
-#declare -i lossNano2=-1
-#declare -i lossNano3=-1
-
-#echo -e "\e[1;32m**** 2. Check if all Nano'IP Address is OK ? ****\e[0m"
-
-#until (( lossNano1 + lossNano2 + lossNano3 == 0 ))
-#do
-#	lossNano1=`ping -c 2 -w 2 $Nano1 | grep loss | awk '{print $6}' | awk -F "%" '{print $1}'`
-#	echo $lossNano1
-#
-#	lossNano2=`ping -c 2 -w 2 $Nano2 | grep loss | awk '{print $6}' | awk -F "%" '{print $1}'`
-#	echo $lossNano2
-#
-#	lossNano3=`ping -c 2 -w 2 $Nano3 | grep loss | awk '{print $6}' | awk -F "%" '{print $1}'`
-#	echo $lossNano3
-#	#sleep 10
-#done
-
-#echo "	IP is Right!"
-
-## GET PC's Address
-localIPAddr=`ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6| head -n 1 | awk '{print $2}'|tr -d "addr:"`
-echo "Local Address: "$localIPAddr
-
-echo -e "\e[1;32m**** 2. Start Main Application ... ****\e[0m"
-if [ $localIPAddr == $Nano3 ];then
-	echo "	MasterNano"
-	############### MasterNano doing things!!!!
-	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqMNConfig.yaml; exec bash"
-	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/pyScripts; python3 live_human_pose.py; exec bash"
-
-elif [ $localIPAddr == $Nano2 ];then
-	echo "	SecNanoLeft"
-	############### SecNanoLeft(3-4) doing things!!!!
-	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNLConfig.yaml; exec bash"
-	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNLConfig.yaml 1; exec bash"
-
-elif [ $localIPAddr == $Nano1 ];then
-	echo "	SecNanoRight"
-	############### SecNanoRight(1-2) doing things!!!!
-	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNRConfig.yaml; exec bash"
-	gnome-terminal -- bash -c "export GST_PLUGIN_PATH=/home/unitree/Unitree/autostart/imageai/mLComSystemFrame/ThirdParty/webSinkPipe/build; cd $mLRootPATH/mLComSystemFrame/bin; ./mqttControlNode ../config/mqSNNRConfig.yaml 1; exec bash"
-else
-	echo "	Not Found $localIPAddr in IP-Clump!"
-fi
-
-echo "	EveryThing is done!"

From 20cd79eac29787d443f8965858da6af50fa74212 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 29 Aug 2022 15:24:29 +0900
Subject: [PATCH 70/77] [jsk_unitree_startup] Copy data to  jetson nano 2gb
 (192.168.123.13)

---
 jsk_unitree_robot/cross/install.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/jsk_unitree_robot/cross/install.sh b/jsk_unitree_robot/cross/install.sh
index fce1d02c5f..85029d4d77 100755
--- a/jsk_unitree_robot/cross/install.sh
+++ b/jsk_unitree_robot/cross/install.sh
@@ -137,6 +137,7 @@ function copy_data () {
 
 if [[ ${TYPE} == "Pro" ]] ; then
     copy_data pi 192.168.123.161
+    copy_data unitree 192.168.123.13
     copy_data unitree 192.168.123.14
     ## copy_data unitree 192.168.123.15 : Pro : No Space for auto start
 elif [[ ${TYPE} == "Air" ]] ; then

From 70cc9f94099aa26a6a2b0f0fa8920b4dc447f2b9 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 29 Aug 2022 15:24:48 +0900
Subject: [PATCH 71/77] [jsk_unitree_startup] Publish image via mqtt

---
 .../scripts/publish_human_pose.diff             | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff b/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff
index 960c221f2f..cfae1f90d7 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/publish_human_pose.diff
@@ -1,6 +1,12 @@
 --- live_human_pose.py	2022-05-26 00:17:04.634784206 +0900
 +++ live_human_pose_jsk.py	2022-05-26 00:17:18.102931810 +0900
-@@ -169,6 +169,8 @@
+@@ -1,4 +1,5 @@
+ #coding:utf-8
++import base64
+ import json
+ import trt_pose . coco
+ import trt_pose . models
+@@ -169,6 +171,8 @@
      if 39 - 39: o00ooo0 - II111iiii * OoO0O00 % o0oOOo0O0Ooo * II111iiii % II111iiii
      cv2 . circle ( src , ( i1I1iI , o0O ) , 8 , I1i1I1II , - 1 )
   iI1Ii11111iIi . write ( src )
@@ -9,3 +15,12 @@
  # cv2 . imshow ( "ai" , src )
  # cv2 . waitKey ( 1 )
   if 59 - 59: iIii1I11I1II1 + I1IiiI - o0oOOo0O0Ooo - I1IiiI + Oo / I1ii11iIi11i
+@@ -199,6 +203,8 @@
+  print ( "AI is working ...." , camIndex . value )
+  Oo0oOOo , Oo0OoO00oOO0o = o0OOO [ camIndex . value - 1 ] . read ( )
+  OOO00O = time . time ( )
++ # add by iory 2022.8.6
++ O0ii1ii1ii.publish("vision/front_camera", base64.b64encode(cv2.imencode('.jpg', Oo0OoO00oOO0o, [int(cv2.IMWRITE_JPEG_QUALITY), 90])[1]).decode('ascii'))
+  OOoOO0oo0ooO = cv2 . resize ( Oo0OoO00oOO0o , dsize = ( OooO0 , II11iiii1Ii ) , interpolation = cv2 . INTER_AREA )
+  iI ( OOoOO0oo0ooO , Oo0OoO00oOO0o , OOO00O )
+  if 98 - 98: I1II1 * I1II1 / I1II1 + O00ooOO

From 096165e0660c94434fa4cfa2a57208fd5d8db9f0 Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Tue, 24 May 2022 22:11:49 +0900
Subject: [PATCH 72/77] [jsk_robot_startup] Add EmailBody msg

---
 jsk_robot_common/jsk_robot_startup/CMakeLists.txt    | 1 +
 jsk_robot_common/jsk_robot_startup/msg/Email.msg     | 2 +-
 jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg | 3 +++
 3 files changed, 5 insertions(+), 1 deletion(-)
 create mode 100644 jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg

diff --git a/jsk_robot_common/jsk_robot_startup/CMakeLists.txt b/jsk_robot_common/jsk_robot_startup/CMakeLists.txt
index 7f597875af..a9ca7f482e 100644
--- a/jsk_robot_common/jsk_robot_startup/CMakeLists.txt
+++ b/jsk_robot_common/jsk_robot_startup/CMakeLists.txt
@@ -59,6 +59,7 @@ add_message_files(
   FILES
   RoomLight.msg
   Email.msg
+  EmailBody.msg
 )
 
 generate_messages(
diff --git a/jsk_robot_common/jsk_robot_startup/msg/Email.msg b/jsk_robot_common/jsk_robot_startup/msg/Email.msg
index 5726aa1477..08cc108e30 100644
--- a/jsk_robot_common/jsk_robot_startup/msg/Email.msg
+++ b/jsk_robot_common/jsk_robot_startup/msg/Email.msg
@@ -1,6 +1,6 @@
 std_msgs/Header header
 string subject # Email subject
-string body # Email body
+jsk_robot_startup/EmailBody[] body # Email body
 string sender_address # Sender's email address
 string receiver_address # receiver's email address
 string smtp_server # smtp server address
diff --git a/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg b/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg
new file mode 100644
index 0000000000..0d50971cef
--- /dev/null
+++ b/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg
@@ -0,0 +1,3 @@
+string type # text, html, img
+string message # For text type
+string file_path # For img type

From 8763099df66eb57bf7c0ba716875aabf77c06030 Mon Sep 17 00:00:00 2001
From: Naoto Tsukamoto <naototukka0413@gmail.com>
Date: Wed, 25 May 2022 14:47:44 +0900
Subject: [PATCH 73/77] [jsk_robot_startup] Support changing embed image size
 and change msg explanation

---
 .../jsk_robot_startup/msg/EmailBody.msg       |  3 +-
 .../jsk_robot_startup/scripts/email_topic.py  | 30 +++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg b/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg
index 0d50971cef..e93849b3d7 100644
--- a/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg
+++ b/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg
@@ -1,3 +1,4 @@
 string type # text, html, img
-string message # For text type
+string message # For text and html type
 string file_path # For img type
+uint8 img_size # For img type [percent]
diff --git a/jsk_robot_common/jsk_robot_startup/scripts/email_topic.py b/jsk_robot_common/jsk_robot_startup/scripts/email_topic.py
index 9918e174d8..10b309a75c 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/email_topic.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/email_topic.py
@@ -76,6 +76,36 @@ def _send_mail(
         msg["From"] = sender_address
         msg["To"] = receiver_address
         msg.attach(MIMEText(body, 'plain', 'utf-8'))
+        # Support embed image
+        for content in body:
+            if content.type == 'text':
+                msg.attach(MIMEText(content.message, 'plain', 'utf-8'))
+            elif content.type == 'html':
+                msg.attach(MIMEText(content.message, 'html'))
+            elif content.type == 'img':
+                if content.file_path == '':
+                    rospy.logwarn('File name is empty. Skipped.')
+                    continue
+                if not os.path.exists(content.file_path):
+                    rospy.logerr(
+                        'File {} is not found.'.format(content.file_path))
+                    return
+                with open(content.file_path, 'rb') as img:
+                    embed_img = MIMEImage(img.read())
+                    embed_img.add_header(
+                        'Content-ID', '<{}>'.format(content.file_path))
+                    msg.attach(embed_img)  # This line is necessary to embed
+                if content.img_size:
+                    image_size = content.img_size
+                else:
+                    image_size = 100
+                text = '<img src="cid:{}" width={}%>'.format(
+                    content.file_path, image_size)
+                bodytext = MIMEText(text, 'html')
+                msg.attach(bodytext)
+            else:
+                rospy.logwarn('Unknown content type {}'.format(content.type))
+                continue
         # Attach file
         for attached_file in attached_files:
             if attached_file == '':

From 56f41d74f9ca5b0c0fe8012c665a2565055dc065 Mon Sep 17 00:00:00 2001
From: Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>
Date: Wed, 27 Jul 2022 18:44:43 +0900
Subject: [PATCH 74/77] add img_data to EmailBody, update email_topic.py and
 email-topic-client.l

---
 .../euslisp/email-topic-client.l              | 20 +++++++++-
 .../euslisp/sample-email-topic-client.l       | 32 +++++++++++++--
 .../jsk_robot_startup/msg/EmailBody.msg       |  3 +-
 .../jsk_robot_startup/scripts/email_topic.py  | 40 ++++++++++++-------
 4 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/jsk_robot_common/jsk_robot_startup/euslisp/email-topic-client.l b/jsk_robot_common/jsk_robot_startup/euslisp/email-topic-client.l
index a78d46de09..8def28a2ff 100644
--- a/jsk_robot_common/jsk_robot_startup/euslisp/email-topic-client.l
+++ b/jsk_robot_common/jsk_robot_startup/euslisp/email-topic-client.l
@@ -1,5 +1,7 @@
 (ros::load-ros-manifest "jsk_robot_startup")
 
+(require :base64 "lib/llib/base64.l")
+
 (defun init-mail ()
   (ros::advertise "email" jsk_robot_startup::Email 1)
   (ros::spin-once)
@@ -16,7 +18,23 @@
   (setq msg (instance jsk_robot_startup::Email :init))
   (send msg :header :stamp (ros::time-now))
   (send msg :subject subject)
-  (send msg :body body)
+  (send msg :body
+        (mapcar #'(lambda (e)
+                    (cond ((derivedp e image-2d)
+                           (if (> (length (send e :entity)) (* 8 8192))
+                               (warning-message 3 "The size of img is too large (~A)~%You may encounter 'too long string' error, see https://github.com/euslisp/EusLisp/issues/2 for more info~%" (length (send e :entity))))
+                           (instance jsk_robot_startup::EmailBody :init :type "img"
+                                     :img_data (base64encode (send e :entity))
+                                     :img_size 100))
+                          ((probe-file e)
+                           (instance jsk_robot_startup::EmailBody :init :type "img" :file_path e :img_size 100))
+                          ((and (> (length e) 0) ;; check html
+                                (eq (elt e 0) #\<)
+                                (eq (elt e (1- (length e))) #\>))
+                           (instance jsk_robot_startup::EmailBody :init :type "html" :message e))
+                          (t
+                           (instance jsk_robot_startup::EmailBody :init :type "text" :message (format nil "~A" e)))))
+                (if (atom body) (list body) body)))
   (send msg :sender_address sender-address)
   (send msg :receiver_address receiver-address)
   (send msg :smtp_server smtp-server)
diff --git a/jsk_robot_common/jsk_robot_startup/euslisp/sample-email-topic-client.l b/jsk_robot_common/jsk_robot_startup/euslisp/sample-email-topic-client.l
index 855b5f9fef..ad280eca65 100755
--- a/jsk_robot_common/jsk_robot_startup/euslisp/sample-email-topic-client.l
+++ b/jsk_robot_common/jsk_robot_startup/euslisp/sample-email-topic-client.l
@@ -7,10 +7,36 @@
 (ros::spin-once)
 (setq receiver-address (ros::get-param "~receiver_address"))
 (setq attached-files (ros::get-param "~attached_files" nil))
-(unix::sleep 10)  ;; wait for server
+(while (or (null (ros::get-num-subscribers "email"))
+           (<= (ros::get-num-subscribers "email") 0))
+  (ros::ros-warn "wait for email topic")
+  (unix::sleep 1))
 
 (ros::ros-info "Sending a mail to ~A" receiver-address)
-(send-mail "test-mail" receiver-address "test" :attached-files attached-files)
-(ros::ros-info "Sent a mail")
+(send-mail "test text mail" receiver-address "test")
+(ros::ros-info "Sent a text mail")
+(unix:sleep 1)
+
+(send-mail "test html mail" receiver-address "<h1>test with html mail</h1>")
+(ros::ros-info "Sent a html mail")
+(unix:sleep 1)
+
+(send-mail "test attached mail" receiver-address "test with attached image" :attached-files attached-files)
+(ros::ros-info "Sent a mail with attached files ~A" attached-files)
+(unix:sleep 1)
+
+(when attached-files
+  (send-mail "test image embedded mail (file)" receiver-address (append attached-files (list "test with embedded image")))
+  (ros::ros-info "sent a mail with embedded image ~a" attached-files)
+  (unix:sleep 1)
+  ;; read png/jpeg file, but do not extract to raw image, keep original compressed data in (img . entity)
+  (setq img (read-image-file (elt attached-files 0)))
+  (setq (img . entity) (make-string (elt (unix:stat (elt attached-files 0)) 7))) ;; size of file
+  (with-open-file (f (elt attached-files 0)) (unix:uread (send f :infd) (img . entity)))
+  (send-mail "test image embedded mail (string)" receiver-address (list "test with embedded image" img))
+  (ros::ros-info "Sent a mail with embedded image ~A" img)
+  (unix:sleep 1)
+  )
+
 (ros::roseus "shutdown")
 (exit)
diff --git a/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg b/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg
index e93849b3d7..db3626ff0a 100644
--- a/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg
+++ b/jsk_robot_common/jsk_robot_startup/msg/EmailBody.msg
@@ -1,4 +1,5 @@
 string type # text, html, img
 string message # For text and html type
-string file_path # For img type
+string file_path # For img type, set file path
+string img_data # For img type, you can also use base64 encoded image data instead of file path
 uint8 img_size # For img type [percent]
diff --git a/jsk_robot_common/jsk_robot_startup/scripts/email_topic.py b/jsk_robot_common/jsk_robot_startup/scripts/email_topic.py
index 10b309a75c..4ec7f06f5b 100755
--- a/jsk_robot_common/jsk_robot_startup/scripts/email_topic.py
+++ b/jsk_robot_common/jsk_robot_startup/scripts/email_topic.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
 from email.mime.application import MIMEApplication
+from email.mime.image import MIMEImage
 from email.mime.text import MIMEText
 from email.mime.multipart import MIMEMultipart
 import errno
@@ -12,6 +13,9 @@
 import socket
 from socket import error as socket_error
 import yaml
+import copy
+import random, string  # for image cid
+import base64
 
 
 class EmailTopic(object):
@@ -43,7 +47,11 @@ def __init__(self):
             'email', Email, self._cb, queue_size=1)
 
     def _cb(self, msg):
-        rospy.loginfo('Received an msg: {}'.format(msg))
+        msg_compact = copy.deepcopy(msg)
+        for content in msg_compact.body:
+            if len(content.img_data) >= 64:
+                content.img_data = content.img_data[:64] + "...."
+        rospy.loginfo('Received an msg: {}'.format(msg_compact))
         send_mail_args = {}
         # Set default value for self._send_mail arguments
         send_mail_args['subject'] = ''
@@ -75,7 +83,6 @@ def _send_mail(
         msg["Subject"] = subject
         msg["From"] = sender_address
         msg["To"] = receiver_address
-        msg.attach(MIMEText(body, 'plain', 'utf-8'))
         # Support embed image
         for content in body:
             if content.type == 'text':
@@ -83,24 +90,27 @@ def _send_mail(
             elif content.type == 'html':
                 msg.attach(MIMEText(content.message, 'html'))
             elif content.type == 'img':
-                if content.file_path == '':
-                    rospy.logwarn('File name is empty. Skipped.')
+                if content.img_data != '':
+                    embed_img = MIMEImage(base64.b64decode(content.img_data))
+                    cid = ''.join(random.choice(string.ascii_lowercase) for i in range(16))
+                elif os.path.exists(content.file_path):
+                    with open(content.file_path, 'rb') as img:
+                        embed_img = MIMEImage(img.read())
+                    cid = content.file_path
+                else:
+                    rospy.logerr("'img' content requries either file_path {}".format(content.type))
+                    rospy.logerr("                           or img_data {} with img_format {}".format(content.img_data, content.img_format))
                     continue
-                if not os.path.exists(content.file_path):
-                    rospy.logerr(
-                        'File {} is not found.'.format(content.file_path))
-                    return
-                with open(content.file_path, 'rb') as img:
-                    embed_img = MIMEImage(img.read())
-                    embed_img.add_header(
-                        'Content-ID', '<{}>'.format(content.file_path))
-                    msg.attach(embed_img)  # This line is necessary to embed
+                embed_img.add_header(
+                    'Content-ID', '<{}>'.format(cid))
+                embed_img.add_header(
+                    'Content-Disposition', 'inline; filename="{}"'.format(os.path.basename(cid)))
+                msg.attach(embed_img)  # This line is necessary to embed
                 if content.img_size:
                     image_size = content.img_size
                 else:
                     image_size = 100
-                text = '<img src="cid:{}" width={}%>'.format(
-                    content.file_path, image_size)
+                text = '<img src="cid:{}" width={}%>'.format(cid, image_size)
                 bodytext = MIMEText(text, 'html')
                 msg.attach(bodytext)
             else:

From 61209bc89990d9be04dd2b6f00b3b85e760f42c5 Mon Sep 17 00:00:00 2001
From: Kei Okada <k-okada@jsk.t.u-tokyo.ac.jp>
Date: Wed, 29 Jun 2022 20:29:33 +0900
Subject: [PATCH 75/77] add node to publish smach_state of lead_teleop program

---
 .../launch/lead_teleop.launch                 |  4 ++
 .../scripts/lead-teleop-state.l               | 61 +++++++++++++++++++
 2 files changed, 65 insertions(+)
 create mode 100755 jsk_unitree_robot/jsk_unitree_startup/scripts/lead-teleop-state.l

diff --git a/jsk_unitree_robot/jsk_unitree_startup/launch/lead_teleop.launch b/jsk_unitree_robot/jsk_unitree_startup/launch/lead_teleop.launch
index 975f4c99df..c4339a9d80 100644
--- a/jsk_unitree_robot/jsk_unitree_startup/launch/lead_teleop.launch
+++ b/jsk_unitree_robot/jsk_unitree_startup/launch/lead_teleop.launch
@@ -29,4 +29,8 @@
     <arg name="joystick_teleop_param_file" default="$(find jsk_unitree_startup)/config/lead_joystick_teleop.yaml" />
   </include>
 
+  <!-- smach node to tell current status  -->
+  <node pkg="jsk_unitree_startup" type="lead-teleop-state.l"
+        name="lead_teleop_state" />
+
 </launch>
diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/lead-teleop-state.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/lead-teleop-state.l
new file mode 100755
index 0000000000..4a6095f05f
--- /dev/null
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/lead-teleop-state.l
@@ -0,0 +1,61 @@
+#!/usr/bin/env roseus
+
+(load "package://roseus_smach/src/state-machine-ros.l")
+
+(ros::roseus-add-msgs "jsk_recognition_msgs")
+
+(setq find-person-msg (instance jsk_recognition_msgs::PeoplePoseArray :init))
+(defun find-person-cb (msg)
+  (setq find-person-msg msg))
+
+(defun start-func (args)
+  (let ()
+    (set-alist 'description "Start Walking" args)
+    :started))
+
+(defun walk-func (args)
+  (let ((last-time-seen-person 9999))
+    (while (> last-time-seen-person 5)
+      (setq last-time-seen-person (send (ros::time- (ros::time-now) (send find-person-msg :header :stamp)) :to-sec))
+      (ros::ros-info "walk  : detect person ~A sec ago" last-time-seen-person)
+      (ros::spin-once)
+      (ros::sleep))
+    ;; set description and goes to next state
+    (set-alist 'description "Find Person" args)
+    :find-person))
+
+(defun find-person-func (args)
+  (let ((last-time-seen-person 0))
+    (while (< last-time-seen-person 5)
+      (setq last-time-seen-person (send (ros::time- (ros::time-now) (send find-person-msg :header :stamp)) :to-sec))
+      (ros::ros-info "person: detect person ~A sec ago" last-time-seen-person)
+      (ros::spin-once)
+      (ros::sleep))
+    ; set description and goes to next state
+    (set-alist 'description "Start Walking" args)
+    :walk))
+
+(defun lead-teleop-sm ()
+  (let (sm)
+    (setq sm
+          (make-state-machine
+           '((:start :started :walk)
+             (:walk :find-person :find-person)
+             (:walk :finished :end)
+             (:find-person :walk :walk))
+           '((:start 'start-func)
+             (:end '(lambda (&rest args) :finished))
+             (:walk 'walk-func) ;; function maps
+             (:find-person 'find-person-func))
+           '(:start)      ;; initial
+           '(:end)       ;; goal
+           ))
+    (send sm :arg-keys 'description)
+    sm))
+
+(ros::roseus "lead-teleop-smach")
+(ros::rate 1)
+(ros::subscribe "/people_pose" jsk_recognition_msgs::PeoplePoseArray #'find-person-cb)
+;; state machine
+(exec-state-machine (lead-teleop-sm))
+(ros::exit)

From c3b18f9ef34cc310de2fdd5a36b75f97429a4984 Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 29 Aug 2022 16:55:40 +0900
Subject: [PATCH 76/77] [jsk_unitree_startup/human_pose_publisher.py] Add
 timestamp for people pose

---
 .../jsk_unitree_startup/scripts/human_pose_publisher.py          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/human_pose_publisher.py b/jsk_unitree_robot/jsk_unitree_startup/scripts/human_pose_publisher.py
index c0a130588a..930f0a907f 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/scripts/human_pose_publisher.py
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/human_pose_publisher.py
@@ -84,6 +84,7 @@ def on_message(client, userdata, msg):
 
             rospy.loginfo("Received `{}` from `{}` topic".format(msg.payload.decode(), msg.topic))
             poses_msg = PeoplePoseArray()
+            poses_msg.header.stamp = self.last_received
             for topic in eval(msg.payload.decode()):  # convert str to list by eval()
                 pose_msg = PeoplePose()
                 for limb, pos in topic.items():

From e6ab4830fa8f6ffc3d17b97906ccbd140e4a629c Mon Sep 17 00:00:00 2001
From: iory <ab.ioryz@gmail.com>
Date: Mon, 29 Aug 2022 16:56:00 +0900
Subject: [PATCH 77/77] [jsk_unitree_startup/llead-teleop-state.l] Check
 detected person

---
 .../jsk_unitree_startup/scripts/lead-teleop-state.l         | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/jsk_unitree_robot/jsk_unitree_startup/scripts/lead-teleop-state.l b/jsk_unitree_robot/jsk_unitree_startup/scripts/lead-teleop-state.l
index 4a6095f05f..63ee24a480 100755
--- a/jsk_unitree_robot/jsk_unitree_startup/scripts/lead-teleop-state.l
+++ b/jsk_unitree_robot/jsk_unitree_startup/scripts/lead-teleop-state.l
@@ -16,7 +16,8 @@
 (defun walk-func (args)
   (let ((last-time-seen-person 9999))
     (while (> last-time-seen-person 5)
-      (setq last-time-seen-person (send (ros::time- (ros::time-now) (send find-person-msg :header :stamp)) :to-sec))
+      (when (> (length (send find-person-msg :poses)) 0)
+        (setq last-time-seen-person (send (ros::time- (ros::time-now) (send find-person-msg :header :stamp)) :to-sec)))
       (ros::ros-info "walk  : detect person ~A sec ago" last-time-seen-person)
       (ros::spin-once)
       (ros::sleep))
@@ -27,7 +28,8 @@
 (defun find-person-func (args)
   (let ((last-time-seen-person 0))
     (while (< last-time-seen-person 5)
-      (setq last-time-seen-person (send (ros::time- (ros::time-now) (send find-person-msg :header :stamp)) :to-sec))
+      (when (> (length (send find-person-msg :poses)) 0)
+        (setq last-time-seen-person (send (ros::time- (ros::time-now) (send find-person-msg :header :stamp)) :to-sec)))
       (ros::ros-info "person: detect person ~A sec ago" last-time-seen-person)
       (ros::spin-once)
       (ros::sleep))