スキップしてメイン コンテンツに移動

Apex.AI: Autoware (강의1)

강의 1: 오리엔테이션 & 개발 환경 설정

0. 자율주행 시장의 확대와 ROS의 보급, Autoware에 대한 소개

자세한 내용은 유튜브 참고하자.(https://youtu.be/XTmlhvlmcf8)

1. ADE install 하기


처음 설치하면 도커 컨테이너를 다운받으면서 환경을 설정하는데 시간이 걸린다.
만약에 설치 환경에 도커가 안깔려 있는 경우, ADE 설치 전에 도커 설치해야한다.

sip2@sip2-NG-N-i5750:~$ mkdir adehome
sip2@sip2-NG-N-i5750:~$ cd adehome
sip2@sip2-NG-N-i5750:~/adehome$ wget https://gitlab.com/ApexAI/ade-cli/uploads/85a5af81339fe55555ee412f9a3a734b/ade+x86_64
--2020-05-12 21:26:34--  https://gitlab.com/ApexAI/ade-cli/uploads/85a5af81339fe55555ee412f9a3a734b/ade+x86_64
Resolving gitlab.com (gitlab.com)... 2606:4700:90:0:f22e:fbec:5bed:a9b9, 172.65.251.78
Connecting to gitlab.com (gitlab.com)|2606:4700:90:0:f22e:fbec:5bed:a9b9|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7999712 (7.6M) [application/octet-stream]
Saving to: ‘ade+x86_64’

ade+x86_64                100%[==================================>]   7.63M  2.03MB/s    in 3.9s    

2020-05-12 21:26:38 (1.96 MB/s) - ‘ade+x86_64’ saved [7999712/7999712]

sip2@sip2-NG-N-i5750:~/adehome$ mv ade+x86_64 ade
sip2@sip2-NG-N-i5750:~/adehome$ chmod +x ade
sip2@sip2-NG-N-i5750:~/adehome$ mv ade ~/.local/bin
sip2@sip2-NG-N-i5750:~/adehome$ which ade
/home/sip2/.local/bin/ade
sip2@sip2-NG-N-i5750:~/adehome$ ade update-cli
ADE cli is up-to-date.
sip2@sip2-NG-N-i5750:~/adehome$ touch .adehome
sip2@sip2-NG-N-i5750:~/adehome$ git clone --recurse-submodules https://gitlab.com/autowarefoundation/autoware.auto/AutowareAuto.git
Cloning into 'AutowareAuto'...
remote: Enumerating objects: 2468, done.
remote: Counting objects: 100% (2468/2468), done.
remote: Compressing objects: 100% (944/944), done.
remote: Total 9367 (delta 1829), reused 1955 (delta 1474), pack-reused 6899
Receiving objects: 100% (9367/9367), 11.83 MiB | 2.04 MiB/s, done.
Resolving deltas: 100% (5318/5318), done.
Submodule 'src/motion/mpc' (https://gitlab.com/aninnymouse/mpc.git) registered for path 'src/external/mpc'
Cloning into '/home/sip2/adehome/AutowareAuto/src/external/mpc'...
remote: Enumerating objects: 772, done.        
remote: Counting objects: 100% (772/772), done.        
remote: Compressing objects: 100% (432/432), done.        
remote: Total 2302 (delta 366), reused 625 (delta 257), pack-reused 1530        
Receiving objects: 100% (2302/2302), 427.77 KiB | 2.11 MiB/s, done.
Resolving deltas: 100% (1142/1142), done.
Submodule path 'src/external/mpc': checked out '0fdacb5fbe930a5882e65b08c985ba1ae147bef9'
sip2@sip2-NG-N-i5750:~/adehome/AutowareAuto$ ade start
Starting ade with the following images:
ade          | 18425565a9fd | master | registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto/ade:master
ade-atom     | v1.39.1      | latest | registry.gitlab.com/apexai/ade-atom:latest                                  
autowareauto | c9dbc109642c | master | registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto:master    
ade_registry.gitlab.com_apexai_ade-atom_latest
ade_registry.gitlab.com_autowarefoundation_autoware.auto_autowareauto_master
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
ERROR: Command return non-zero exit code (see above): 125
  docker run -h ade --detach --name ade --env COLORFGBG --env DISPLAY --env EMAIL --env GIT_AUTHOR_EMAIL --env GIT_AUTHOR_NAME --env GIT_COMMITTER_EMAIL --env GIT_COMMITTER_NAME --env SSH_AUTH_SOCK --env TERM --env TIMEZONE=Asia/Tokyo --env USER=sip2 --env GROUP=sip2 --env USER_ID=1000 --env GROUP_ID=1000 --env VIDEO_GROUP_ID=44 -v /dev/dri:/dev/dri -v /dev/shm:/dev/shm -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/sip2/adehome:/home/sip2 --env ADE_CLI_VERSION=4.1.0 --env ADE_HOME_HOSTPATH=/home/sip2/adehome --label ade_version=4.1.0 -v /home/sip2/.ssh:/home/sip2/.ssh -v /run/user/1000/keyring/ssh:/run/user/1000/keyring/ssh --volumes-from ade_registry.gitlab.com_apexai_ade-atom_latest:ro --volumes-from ade_registry.gitlab.com_autowarefoundation_autoware.auto_autowareauto_master:ro --label 'ade_volumes_from=["ade_registry.gitlab.com_apexai_ade-atom_latest", "ade_registry.gitlab.com_autowarefoundation_autoware.auto_autowareauto_master"]' --gpus all --env NVIDIA_VISIBLE_DEVICES=all --env NVIDIA_DRIVER_CAPABILITIES=compute,utility,graphics,display --env LD_LIBRARY_PATH=/usr/local/nvidia/lib64 --cap-add=SYS_PTRACE --env ADE_IMAGE_ADE_FQN=registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto/ade:master --env ADE_IMAGE_ADE_COMMIT_SHA=18425565a9fdfd2b5e9a8fd837f18f8bbd99d961 --env ADE_IMAGE_ADE_COMMIT_TAG= --env ADE_IMAGE_ADE_ATOM_FQN=registry.gitlab.com/apexai/ade-atom:latest --env ADE_IMAGE_ADE_ATOM_COMMIT_SHA=41a804c93041bf2ef4fe118676a4b6a84bdeff91 --env ADE_IMAGE_ADE_ATOM_COMMIT_TAG=v1.39.1 --env ADE_IMAGE_AUTOWAREAUTO_FQN=registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto:master --env ADE_IMAGE_AUTOWAREAUTO_COMMIT_SHA=c9dbc109642c64dd2c618fffaa3bfabb995c7b26 --env ADE_IMAGE_AUTOWAREAUTO_COMMIT_TAG= --label 'ade_images=[{"fqn": "registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto/ade:master", "commit_sha": "18425565a9fdfd2b5e9a8fd837f18f8bbd99d961", "commit_tag": ""}, {"fqn": "registry.gitlab.com/apexai/ade-atom:latest", "commit_sha": "41a804c93041bf2ef4fe118676a4b6a84bdeff91", "commit_tag": "v1.39.1"}, {"fqn": "registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto:master", "commit_sha": "c9dbc109642c64dd2c618fffaa3bfabb995c7b26", "commit_tag": ""}]' registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto/ade:master

동영상 보고 그대로 설치 했는데 에러가 뜬다.
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
ERROR: Command return non-zero exit code (see above): 125

구글링해서 찾아보니까 아래의 질문을 발견

sip2@sip2-NG-N-i5750:~$ sudo systemctl restart docker

하고나서 다시 실행하니까 작동한다.

sip2@sip2-NG-N-i5750:~/adehome/AutowareAuto$ ade start
Starting ade with the following images:
ade          | 18425565a9fd | master | registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto/ade:master
ade-atom     | v1.39.1      | latest | registry.gitlab.com/apexai/ade-atom:latest                                  
autowareauto | c9dbc109642c | master | registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto:master    
ade_registry.gitlab.com_apexai_ade-atom_latest
ade_registry.gitlab.com_autowarefoundation_autoware.auto_autowareauto_master
non-network local connections being added to access control list

Current default time zone: 'Asia/Tokyo'
Local time is now:      Tue May 12 21:55:38 JST 2020.
Universal Time is now:  Tue May 12 12:55:38 UTC 2020.

Adding user sip2 to group video
Adding user sip2 to group dialout
Initializing /opt/atom
Doing initial install of atom plugins:
Installing atom-beautify to /home/sip2/.atom/packages ✓
Installing atom-ide-ui to /home/sip2/.atom/packages ✓
Installing atom-ide-debugger-native-gdb to /home/sip2/.atom/packages ✓
Installing atom-ide-debugger-python to /home/sip2/.atom/packages ✓
Installing autocomplete-clang to /home/sip2/.atom/packages ✓
Installing build to /home/sip2/.atom/packages ✓
Installing build-colcon to /home/sip2/.atom/packages ✓
Installing busy-signal to /home/sip2/.atom/packages ✓
Installing highlight-selected to /home/sip2/.atom/packages ✓
Installing ide-python to /home/sip2/.atom/packages ✓
Installing intentions to /home/sip2/.atom/packages ✓
Installing language-cmake to /home/sip2/.atom/packages ✓
Installing language-docker to /home/sip2/.atom/packages ✓
Installing linter to /home/sip2/.atom/packages ✓
Installing linter-docker to /home/sip2/.atom/packages ✓
Installing linter-shellcheck to /home/sip2/.atom/packages ✓
Installing linter-ui-default to /home/sip2/.atom/packages ✓
Installing minimap to /home/sip2/.atom/packages ✓
Installing minimap-highlight-selected to /home/sip2/.atom/packages ✓
Installing minimap-split-diff to /home/sip2/.atom/packages ✓
Installing platformio-ide-terminal to /home/sip2/.atom/packages ✓
Installing pretty-json to /home/sip2/.atom/packages ✓
Installing split-diff to /home/sip2/.atom/packages ✓
Initial install of atom plugins done.
Initializing /opt/atom done
ADE startup completed.

ADE has been started, enter or run commands using: ade enter

sip2@sip2-NG-N-i5750:~/adehome/AutowareAuto$ ade enter
Entering ade with following images:
ade          | 18425565a9fd | master | registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto/ade:master
ade-atom     | v1.39.1      | latest | registry.gitlab.com/apexai/ade-atom:latest                                  
autowareauto | c9dbc109642c | master | registry.gitlab.com/autowarefoundation/autoware.auto/autowareauto:master    
sip2@ade:~$ 

설치성공했다.

sip2@ade:~$ ros2 -h
usage: ros2 [-h] Call `ros2 <command> -h` for more detailed usage. ...

ros2 is an extensible command-line tool for ROS 2.

optional arguments:
  -h, --help            show this help message and exit

Commands:
  action     Various action related sub-commands
  bag        Various rosbag related sub-commands
  component  Various component related sub-commands
  daemon     Various daemon related sub-commands
  launch     Run a launch file
  lifecycle  Various lifecycle related sub-commands
  msg        Various msg related sub-commands
  multicast  Various multicast related sub-commands
  node       Various node related sub-commands
  param      Various param related sub-commands
  pkg        Various package related sub-commands
  run        Run a package specific executable
  security   Various security related sub-commands
  service    Various service related sub-commands
  srv        Various srv related sub-commands
  test       Run a ROS2 launch test
  topic      Various topic related sub-commands

  Call `ros2 <command> -h` for more detailed usage.

sip2@ade:~$ ros2 run demo_nodes_cpp talker
[INFO] [talker]: Publishing: 'Hello World: 27'
[INFO] [talker]: Publishing: 'Hello World: 28'
[INFO] [talker]: Publishing: 'Hello World: 29'
[INFO] [talker]: Publishing: 'Hello World: 30'
[INFO] [talker]: Publishing: 'Hello World: 31'
[INFO] [talker]: Publishing: 'Hello World: 32'
[INFO] [talker]: Publishing: 'Hello World: 33'
[INFO] [rclcpp]: signal_handler(signal_value=2)

sip2@ade:~$ ros2 run demo_nodes_cpp listener
[INFO] [listener]: I heard: [Hello World: 27]
[INFO] [listener]: I heard: [Hello World: 28]
[INFO] [listener]: I heard: [Hello World: 29]
[INFO] [listener]: I heard: [Hello World: 30]
[INFO] [listener]: I heard: [Hello World: 31]
[INFO] [listener]: I heard: [Hello World: 32]
[INFO] [rclcpp]: signal_handler(signal_value=2)

sip2@ade:~$ ls /opt/AutowareAuto/
bin            include  local_setup.bash  _local_setup_util_ps1.py  setup.bash  setup.zsh
cmake          lib      local_setup.ps1   _local_setup_util_sh.py   setup.ps1   share
COLCON_IGNORE  LICENSE  local_setup.sh    local_setup.zsh           setup.sh    src

2. Object Detection Demo 돌려보기

${HOME}/adehome/data 에 pcap 파일 다운 받기.

sip2@ade:~$ git clone https://gitlab.com/ApexAI/autowareclass2020.git ~/autowareclass2020
Cloning into '/home/sip2/autowareclass2020'...
remote: Enumerating objects: 130, done.
remote: Counting objects: 100% (130/130), done.
remote: Compressing objects: 100% (83/83), done.
remote: Total 130 (delta 37), reused 109 (delta 29), pack-reused 0
Receiving objects: 100% (130/130), 7.13 MiB | 1.08 MiB/s, done.
Resolving deltas: 100% (37/37), done.

new window
sip2@ade:~$ udpreplay ~/data/route_small_loop_rw-127.0.0.1.pcap -r -1

new window
sip2@ade:~$ source /opt/AutowareAuto/setup.bash
not found: "/opt/AutowareAuto/share/spinnaker_camera_driver/local_setup.bash"
not found: "/opt/AutowareAuto/share/spinnaker_camera_node/local_setup.bash"

sip2@ade:~$ rviz2 -d /home/${USER}/autowareclass2020/code/src/01_DevelopmentEnvironment/aw_class2020.rviz
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-sip2'
[INFO] [rviz2]: Stereo is NOT SUPPORTED
[INFO] [rviz2]: OpenGl version: 4.6 (GLSL 4.6)
[INFO] [rviz2]: Stereo is NOT SUPPORTED
Parsing robot urdf xml string.

new window
sip2@ade:~$ source /opt/AutowareAuto/setup.bash
not found: "/opt/AutowareAuto/share/spinnaker_camera_driver/local_setup.bash"
not found: "/opt/AutowareAuto/share/spinnaker_camera_node/local_setup.bash"

sip2@ade:~$ ros2 run velodyne_node velodyne_cloud_node_exe __ns:=/lidar_front __params:=/home/${USER}/autowareclass2020/code/src/01_DevelopmentEnvironment/velodyne_node.param.yaml

new window
sip2@ade:~$ source /opt/AutowareAuto/setup.bash
not found: "/opt/AutowareAuto/share/spinnaker_camera_driver/local_setup.bash"
not found: "/opt/AutowareAuto/share/spinnaker_camera_node/local_setup.bash"

sip2@ade:~$ ros2 run robot_state_publisher robot_state_publisher /opt/AutowareAuto/share/lexus_rx_450h_description/urdf/lexus_rx_450h.urdf
Initialize urdf model from file: /opt/AutowareAuto/share/lexus_rx_450h_description/urdf/lexus_rx_450h.urdf
Parsing robot urdf xml string.
The root link base_link has an inertia specified in the URDF, but KDL does not support a root link with an inertia.  As a workaround, you can add an extra dummy link to your URDF.
Link gnss had 0 children
Link imu had 0 children
Link lidar_front had 0 children
Link lidar_rear had 0 children
Link nav_base had 0 children
got segment base_link
got segment gnss
got segment imu
got segment lidar_front
got segment lidar_rear
got segment nav_base
Adding fixed segment from base_link to gnss
Adding fixed segment from base_link to imu
Adding fixed segment from base_link to lidar_front
Adding fixed segment from base_link to lidar_rear
Adding fixed segment from base_link to nav_base

new window
sip2@ade:~$ source /opt/AutowareAuto/setup.bash
not found: "/opt/AutowareAuto/share/spinnaker_camera_driver/local_setup.bash"
not found: "/opt/AutowareAuto/share/spinnaker_camera_node/local_setup.bash"

sip2@ade:~$ ros2 run point_cloud_filter_transform_nodes  point_cloud_filter_transform_node_exe __ns:=/lidar_front __params:=/opt/AutowareAuto/share/point_cloud_filter_transform_nodes/param/vlp16_sim_lexus_filter_transform.param.yaml __node:=filter_transform_vlp16_front

new window
sip2@ade:~$ source /opt/AutowareAuto/setup.bash
not found: "/opt/AutowareAuto/share/spinnaker_camera_driver/local_setup.bash"
not found: "/opt/AutowareAuto/share/spinnaker_camera_node/local_setup.bash"

sip2@ade:~$ ros2 run ray_ground_classifier_nodes ray_ground_classifier_cloud_node_exe __ns:=/perception __params:=/opt/AutowareAuto/share/autoware_auto_avp_demo/param/ray_ground_classifier.param.yaml
[INFO] [perception.ray_ground_classifier]: RayGroundClassifier has activated

new window
sip2@ade:~$ source /opt/AutowareAuto/setup.bash
not found: "/opt/AutowareAuto/share/spinnaker_camera_driver/local_setup.bash"
not found: "/opt/AutowareAuto/share/spinnaker_camera_node/local_setup.bash"

sip2@ade:~$ ros2 run  euclidean_cluster_nodes euclidean_cluster_exe __ns:=/perception __params:=/opt/AutowareAuto/share/autoware_auto_avp_demo/param/euclidean_cluster.param.yaml

Rviz에 다음과 같이 나타난다

결과 화면

예전에 autoware에서는 GUI을 제공해주었는데, ADE는 GUI가 없는건가?
아직 돌려보기만 해서 잘 모르겠다. 앞으로 강의를 들으면서 차근차근 알아봐야겠다.

아래는 동영상


3. 패키지 생성하고 컴파일 해보기

sip2@ade:~$ cd ~/AutowareAuto/src/
sip2@ade:~/AutowareAuto/src (master u=)$ autoware_auto_create_pkg --destination . --pkg-name autoware_my_first_pkg --maintainer "Dejan Pangercic" --email dejan@apex.ai --description "My first Autoware pkg."
Package autoware_my_first_pkg has been generated in ..
sip2@ade:~/AutowareAuto/src (master % u=)$ ls autoware_my_first_pkg/
CMakeLists.txt  design  include  package.xml  src  test

sip2@ade:~/AutowareAuto/src (master % u=)$ emacs -nw autoware_my_first_pkg/src/autoware_my_first_pkg_node.cpp

귀찮으니까 간단히 헬로월드 찍어보자.

int32_t autoware_my_first_pkg_c::print_hello() const
{
  std::cerr << "hello world" << std::endl;
  return autoware_my_first_pkg::print_hello();
}

sip2@ade:~/AutowareAuto/src (master % u=)$ cd ..
sip2@ade:~/AutowareAuto (master % u=)$ colcon build --packages-select autoware_auto_autoware_my_first_pkg
Starting >>> autoware_auto_autoware_my_first_pkg
Finished <<< autoware_auto_autoware_my_first_pkg [5.26s]                       

Summary: 1 package finished [5.73s]

sip2@ade:~/AutowareAuto (master % u=)$ source install/setup.bash
not found: "/opt/AutowareAuto/share/spinnaker_camera_driver/local_setup.bash"
not found: "/opt/AutowareAuto/share/spinnaker_camera_node/local_setup.bash"
not found: "/home/sip2/AutowareAuto/install/spinnaker_camera_driver/share/spinnaker_camera_driver/local_setup.bash"
not found: "/home/sip2/AutowareAuto/install/spinnaker_camera_node/share/spinnaker_camera_node/local_setup.bash"

sip2@ade:~/AutowareAuto (master % u=)$ ros2 run autoware_auto_autoware_my_first_pkg autoware_my_first_pkg_exe
hello world
Hello World

환경 설정 강의는 여기까지.. 다음 강의는 내일 들어야 겠다. 피곤하다 ㅠㅠ 늙었어..

4. Safety and Security in Automotive

 연구단계에서 좋은 결과가 나와도 상용화를 위해서는 기존의 수많은 시스템과의 원활한 연동이 필수이다. 이때, 엔지니가 예상하지 못한 상호작용으로 인한 결과로 시스템이 불능 상태 또는 제어 불가 상태가 되더라도, 차량의 전체 시스템에 영향을 주면 안된다. 이는 자동차 업계뿐만 아니라, 건설, 농업기계 등에도 해당된다.

 강의와는 관련 없는 이야기지만, 기존의 차량을 개조 또는 개선하여 자율 주행 차량 플랫폼을 구성하면 기존에 탑재되어 있는 수많은 ECU와 연동되어 유닛 테스트와 전체 테스트를 수행하여 안정성을 검증할 필요가 있다. 이는, 엄청난 개발비용 증가와 잠재 위험을 갖고 있는데, 테슬라는 처음부터 자율주행을 지원하는 차량을 최소한의 ECU로 제어할 수 있게 설계하여 다른 경쟁자들에 비해 효율적으로 연구 개발과 상용화를 동시에 진행하고 있다. 테슬라 주식을 사고 싶다 ㅋㅋㅋ

참고문헌

コメント

このブログの人気の投稿

[참고] ROS kinetic에서 WebCam 사용하기 (Ubuntu 16.04)

Reference: 1. https://github.com/bosch-ros-pkg/usb_cam/issues/53  2. http://zumashi.blogspot.jp/2016/12/ros-kinetic-usb-cam.html  3. http://cafe.naver.com/openrt/5963 위의 사이트들을 참고하여 ROS Kinetic에서 Logitech WebCam C270의 동작을 확인했습니다. $ cd ~/catkin_ws/src $ git clone https://github.com/bosch-ros-pkg/usb-cam.git $ cd .. $ catkin_make WebCam test $ roscore $ rosrun usb_cam usb_cam_node $ rosrun image_view image_view image:=/usb_cam/image_raw $ rosrun rviz rviz 1) By display type>rviz>image 2) Image topic: /usb_cam/image_raw --> 왼쪽 하단과 같이 WebCam이 잘 동작하는 것을 확인했습니다.

[vscode] TImeout waiting for debugger connection

이제까지 잘 동작하던 비주얼 스튜디오 코드가 위와 같은 에러 메세지를 내면서 갑자기 디버깅이 안되서 인터넷을 검색한 결과.. vscode의 User Setting에서 검색창에 python.terminal.activateEnvironment을 입력하여 true로 설정되어 있는 값을 false로 변환하면 된다. 

Anaconda을 이용하여 ROS + Tensorflow 함께 사용하기

-- CUDA, cuDNN 버전확인 https://stackoverflow.com/questions/41714757/how-to-find-cuda-version-in-ubuntu/42122965 $ nvcc --version cuda8.0, cudnn6.0 -- 아나콘다 python2.7 버전 인스톨 https://www.anaconda.com/download/#linux python3.x이랑 ROS 같이 써보려고 했는데, 아직 실력이 부족해서 그런지 실패.. $ bash Anaconda2-5.3.0-Linux-x86_64.sh $ source ~/.bashrc $ python -V Python 2.7.15 :: Anaconda, Inc. $ conda create -n tf14 pip python=2.7 $ source activate tf14 -- ROS 관련 패키지 인스톨 (tf14) $ pip install --upgrade pip (tf14) $ pip install -U rosinstall msgpack empy defusedxml netifaces --CUDA, cuDNN, CPU/GPU을 사양에 맞춰서 tensorflow download https://github.com/mind/wheels#mkl (tf14) $ pip install tensorflow-1.4.0-cp27-cp27mu-linux_x86_64.whl 잘 설치가 되었는지 Hello, tensorflow 실행 (tf14) $ python Python 2.7.15 |Anaconda, Inc.| (default, May  1 2018, 23:32:55) [GCC 7.2.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> i