Edited at

Jetson Nanoにリモートデスクトップ(VNC)環境を用意する


この記事について

nVIDIAのJetson NanoにVNCサーバをインストールして、開発用ホストPC(Windows等)から接続できるようにします。

Jetson Nanoの環境立ち上げも含めて説明します。

(Jetson Nanoに限らず、通常のLinuxでも同じ方法で大丈夫だと思います。)


なぜ必要?

Jetson NanoはUbuntuが起動して、パソコン同等の環境が動きます。

とはいえ、以下のような思いがあります。


  • 実際のコーディングなどは使い慣れたホストPC(Windows/PC Linux等)でやりたい

  • Jetson Nanoにキーボード、マウス、ディスプレイを接続するのが面倒、不可能 (お金的に、スペース的に)


コマンド操作だけなら

もしもやりたいことがコマンド操作だけなら、リモートデスクトップは不要です。

ホストPCでコーディングして、コンパイル・実行だけをJetson Nanoでやるなら、ssh接続さえできれば大丈夫です。実際にはコーディング用のエディタ(VSCode等)に、SSH用プラグインを入れることで、かなりやりやすくなります。 こちらの記事もご参考ください。 ラズパイ用のC/C++開発環境をお手軽に構築する

ただし、その場合でもたまにGUIからの操作が必要だったり、画面出力を確認したい場合があると思います。そのような時に、いちいちHDMI接続を切り替えるのは面倒です。


環境


  • ホストPC


    • Windows 10 (64-bit)

    • Git Bash (sshコマンドが使えれば何でもいい。MSYS,Tera TermでもOK)

    • RealVNC VNC Viewer (他のVNCクライアントでも大丈夫)



  • ターゲット


    • Jetson Nano

    • jetson-nano-sd-r32.1-2019-03-18




一番最初の起動~SSH接続

https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit 通りに進めていけば、イメージ書き込みから初期設定まで完了します。

一番最初の設定と、JetsonNanoのIPアドレスを確認するまでは、Jetson Nanoにキーボード、マウス、ディスプレイを接続する必要があります。


  • イメージを書き込んだSDカードを差し込み、電源ONします。ユーザ名やパスワード、タイムゾーンなどUbuntu OSの初期設定をします。

  • Ubuntuが起動したらDashボタンをクリックし、terminal と入力し、Terminalを起動します。

  • Terminal上で、ifconfig と入力し、Jetson NanoのIPアドレスを確認します。以後、192.168.1.115とします。

ここまで出来たら、もうJetson Nano本体を直接操作する必要はありません。キーボードやHDMIケーブルは外しても大丈夫です。


ホストPCからSSH接続する

ホストPC上のsshが使用可能な端末(例. Git Bash)から、ssh takeshi@192.168.1.115 と入力します。(ユーザ名、IPアドレスは適宜置き換えてください)

パスワードを入力すれば、SSH接続ができるはずです。


リモートデスクトップ(VNC)環境


方針

単にVNCサーバを立ち上げると、本体の画面(HDMI出力)とは別のXが起動されます。組込み環境ではできるだけ負荷を低減させたいのと、そのX用にも別途デスクトップ環境(GNOME等)を用意する必要があり面倒です。(少し試したのですが、アプリケーションの画面がうまく飛んでくれなかったりと、結構ハマりそうでした。)

そのため、本体の画面(HDMI出力)のXをそのまま使用するようにします。(Raspberry Pi標準のVNCと同じ感じにします)


追記

Ubuntuには標準でDesktop Sharing(デスクトップ共有) 機能があります。これを使えば、上記のことはできます。

ただし、2019年4~5月時点のOSイメージだと、設定しようとしたらCrashしてしまうという問題がありました。

もともと本記事は、このDesktop Sharingを使用しないで、TigerVNCを使ってVNC接続する方法を記載していました。

ただ、標準のDesktop Sharingを使えるようにする方法が見つかったので、その内容も併せて記載します。お好きな方をご使用ください。


(方法1) TigerVNCを使う


VNC Serverのインストールと設定

VNCサーバとして、TigerVNCを使用します。

以下コマンドで、インストール、初期設定をします。最後に起動してみます。


SSHターミナル(VNCインストールと設定と手動起動)

sudo apt update

sudo apt install tigervnc-standalone-server tigervnc-scraping-server
vncpasswd

# Would you like to enter a view-only password (y/n)? と聞かれるが、nでよい。

x0vncserver -display :0 -passwordfile ~/.vnc/passwd
# 別途、X環境を作る場合は、vncserver :1 などにする



Windowsから接続してみる

Windows上でVNC Viewerを起動します。

File -> New connection から新しいサーバ設定を追加します。

VNC Server: の所に、ssh接続にも使用したJetson NanoのIPアドレスを設定します。(通常、IPアドレスの最後にコロンとディスプレイ番号を付けます。今回は:0ですが省略可能です)

作成したサーバ設定をダブルクリックして接続します。パスワードは、JetsonNanoのUbuntuパスワードではなく、vncpasswdで設定したパスワードを入力します。

成功したら、Jetson Nanoの画面が表示されるはずです。

関連する画面のスクリーンショットを張っておきます。左上から時計回りに、SSHターミナル、VNC Viewer設定、リモート画面、です。

image.png

接続成功したら、一度VNC Viewerは閉じてください。また、SSHターミナル上でCtrl-Cして、x0vncserverを停止します。


VNC Serverをデーモンとして自動起動させる

VNCサーバを毎回手動で起動するのは面倒なので、システム起動時に自動的にVNCサーバが起動するようにします。

以下コマンドで、systemdのサービス用設定ファイルを作成します。


SSHターミナル

sudo vi /etc/systemd/system/x0vncserver.service


以下のような内容を入力(コピペ)します。

ユーザ名やパスは適宜変更してください。(~/などは使用できませんでした)


/etc/systemd/system/x0vncserver.service

[Unit]

Description=Remote desktop service (VNC)
After=syslog.target
After=network.target remote-fs.target nss-lookup.target
After=x11-common.service

[Service]
Type=forking
User=takeshi
Group=takeshi
WorkingDirectory=/home/takeshi
ExecStart=/bin/sh -c 'sleep 10 && /usr/bin/x0vncserver -display :0 -rfbport 5900 -passwordfile /home/takeshi/.vnc/passwd &'

[Install]
WantedBy=multi-user.target


上記スクリプトで設定した内容が起動時に呼ばれるのですが、まずは手動で呼び出して正しく動くか確認します。


SSHターミナル(Systemdサービス起動確認)

sudo systemctl start x0vncserver.service

sudo systemctl status x0vncserver.service

# 正しく動いていたら、以下のように表示されます。
## x0vncserver.service - Remote desktop service (VNC)
## Loaded: loaded (/etc/systemd/system/x0vncserver.service; disabled; vendor preset: enabled)
## Active: active (running) since Tue 2019-04-30 00:10:57 JST; 51ms ago
## Process: 15752 ExecStart=/bin/sh -c sleep 10 && /usr/bin/x0vncserver -display :0 -rfbport 5900 -passwordfile /home/takeshi/.vnc/passwd & (code=exite
## Main PID: 15753 (sh)
## Tasks: 2 (limit: 4189)
## CGroup: /system.slice/x0vncserver.service
## ├─15753 /bin/sh -c sleep 10 && /usr/bin/x0vncserver -display :0 -rfbport 5900 -passwordfile /home/takeshi/.vnc/passwd &
## └─15755 sleep 10
##
## 4月 30 00:10:57 takeshi-jetson systemd[1]: Starting Remote desktop service (VNC)...
## 4月 30 00:10:57 takeshi-jetson systemd[1]: Started Remote desktop service (VNC).


OKなら、以下コマンドでサービスを有効化して再起動します。


SSHターミナル(Systemdサービス有効化)

sudo systemctl enable x0vncserver.service 

sudo reboot yes

# 再起動後、ちゃんとサービスが起動しているか確認
systemctl list-units | grep vnc
# 正しく動いていたら、以下のように表示されます。
## x0vncserver.service loaded active running Remote desktop service (VNC)


これ以降は何もしないでもVNC接続ができるようになります。


メモ


Systemd設定ファイルに関して

x0vncserver の起動は、X関係の起動を待つ必要があります。待たないと起動に失敗します。

一応、After=x11-common.service として、それっぽいことはしているのですが、うまく行きませんでした。

しょうがないので、sleep 10 するという格好悪い回避策を取りました。

もっといい方法があれば、どなたか教えていただきたいです。


既定のVNCサービスの無効化

systemctl list-units | grep vnc を入力したときに、既にdisplay1 (:1)用のSystemdサービスが登録されている可能性があります。その場合は、sudo systemctl disable vncserver@display:1.serviceなどで無効化しておきます。


クリップボードのサポート

リモート-サーバ間でのクリップボードの共有は未サポートの模様

x0vncserver does not support clipboard

https://github.com/TigerVNC/tigervnc/issues/529


オーバーヘッド

x0vncserverのCPU使用率は、画面に動きがない場合で、2%/400%程度。画面が激しく動いている場合で、40%/400%。

なので、処理時間測定したり、ガチで何かを動かす場合にはリモートデスクトップはOFFにした方が良い


(方法2) Desktop Sharing(Vino)を使う

https://blog.hackster.io/getting-started-with-the-nvidia-jetson-nano-developer-kit-43aa7c298797

の記事の「Enabling Desktop Sharing」 の手順通りです。

基本的には、GNOMEの設定を修正しているだけなので、将来的には何もしないでもOKになると思っています。そうなればこの記事も不要になります。

また、「コンソールからログイン中じゃないとVNC接続できないので、 xrdpをインストールする」みたいなことが書いてありましたが、僕の環境では不要でした。ログイン設定で、Automatically login を有効にしているからかもしれません。(逆に言うと、ログイン画面も出ないので危険ではありますが。)


必要なコマンドと操作抜粋


編集とコンパイルコマンド

sudo nano /usr/share/glib-2.0/schemas/org.gnome.Vino.gschema.xml

sudo glib-compile-schemas /usr/share/glib-2.0/schemas
gsettings set org.gnome.Vino require-encryption false
gsettings set org.gnome.Vino prompt-enabled false


/usr/share/glib-2.0/schemas/org.gnome.Vino.gschema.xml

    <key name='enabled' type='b'>

<summary>Enable remote access to the desktop</summary>
<description>
If true, allows remote access to the desktop via the RFB
protocol. Users on remote machines may then connect to the
desktop using a VNC viewer.
</description>
<default>false</default>
</key>


  • 設定画面からDesktop Sharingを有効にする

  • 自動起動設定



    • Startup Applications Preferences に以下コマンドを追加

    • /usr/lib/vino/vino-server




メモ


アプリケーションの画面だけを飛ばすなら

画面全体ではなくて、アプリケーションのウィンドウだけを見たいなら、X11 Frowardingの方が便利かもしれません。ただ、飛んだり飛ばなかったりします。OpenCVでの画面表示くらいなら大丈夫でした。

https://qiita.com/take-iwiw/items/e52ec08e8c25634a57d7#x11-forwardingでアプリケーション画面を転送する


解像度が低い場合

HDMIをディスプレイに接続していない状態でVNC接続すると、解像度が640x480 になってしまいます。

恐らく、HDMI接続されていないときはフレームバッファが確保されないのではないかと思います。

解決策を https://devtalk.nvidia.com/default/topic/995621/jetson-tx1/jetson-tx1-desktop-sharing-resolution-problem-without-real-monitor/ で見つけました。

/etc/X11/xorg.conf ファイルを以下のように編集します (sudo nano /etc/X11/xorg.conf )。


/etc/X11/xorg.conf

# Copyright (c) 2011-2013 NVIDIA CORPORATION.  All Rights Reserved.

#
# This is the minimal configuration necessary to use the Tegra driver.
# Please refer to the xorg.conf man page for more configuration
# options provided by the X server, including display-related options
# provided by RandR 1.2 and higher.

# Disable extensions not useful on Tegra.
Section "Module"
Disable "dri"
SubSection "extmod"
Option "omit xfree86-dga"
EndSubSection
EndSection

Section "Device"
Identifier "Tegra0"
Driver "nvidia"
# Allow X server to be started even if no display devices are connected.
Option "AllowEmptyInitialConfiguration" "true"
EndSection

Section "Monitor"
Identifier "DSI-0"
Option "Ignore"
EndSection

Section "Screen"
Identifier "Default Screen"
Monitor "Configured Monitor"
Device "Default Device"
SubSection "Display"
Depth 24
Virtual 1280 800
EndSubSection
EndSection



参考

https://wiki.archlinux.jp/index.php/TigerVNC#systemd_.E3.81.A7_x0vncserver_.E3.82.92.E8.B5.B7.E5.8B.95.E3.83.BB.E5.81.9C.E6.AD.A2

https://dev.classmethod.jp/cloud/aws/service-control-use-systemd/

https://qiita.com/Tats_U_/items/c170f61a5e03ae045128

https://devtalk.nvidia.com/default/topic/995621/jetson-tx1/jetson-tx1-desktop-sharing-resolution-problem-without-real-monitor/