VR:Unity空間内をDayDreamコントローラーで歩く1(見る価値なし)

Unity空間内をDayDreamコントローラーで歩きたいとき ありますよね。

UnityでのDaydream(3DoF)コントローラのサポート

結果:無理でした。別途再チャレンジします。

環境

  • OS                          :Windows 10 Home
  • Unity                    :Unity Hub  > Unity 2019.3.0a5
  • google VR SDK : Unity v1.200.0用GVR SDK
  • ヘッドセット:Mirage Solo

Unityへgoogle VRをインポート

GoogleVRForUnity_1.200.0.unitypackage をダウンロードしてUnity内でAssetsフォルダ直下にインポートします。

Android搭載のUnity用Google VR SDKのクイックスタート

その中に、Hello6DoFControllers の説明があるので リンク先にいってみると404 お探しのページはありません・・・と出てきます。自力でやるしかありません。

ビルドエンドら~ん

画面下のProjectメニューにAssets>GoogleVR>Demos>Scenesが追加されているので、>VideoDemo を試してみましょう。この中に、DayDreamコントローラーで歩く方法が実装されているかもしれないという期待をこめて。

ではシーンにチェックを入れて、プラットフォームをアンドロイドにして、ここで問題発生。

プレイヤーセッティングが白紙・・・。設定できない。

まあ、そこは無視して、ヘッドセットとPCをUSBケーブルで繋いで、さあ ビルドエンドら~ん。※私はMirage Soloでやりますので、USBケーブルをPCとヘッドセットに接続してビルドアンドランしてみます。

上手くいきません。それもそのはず、プレイヤーセッティングをやってませんからね・・・。どうしよう。

今一度プレイヤーセッティングに行ってみると、何故か設定項目が復活していたので、Company Name を入れて(多分頭が大文字にしないとだめ)、Other SettingのGraphics APIsでVulkanを削除、Minimun API Level を24に,XR SettingsのVirtual REality Supportedにチェックをいれて、プラスボタンを押してDayDreamを選択。

いろいろ設定して、ビルドしてみます。

target architecture not specified という警告がでるので、target architectureでarm v7を選択(これしか選べない)

これで上手く行くと思いきや、コンソールにアラートが。

unitygvr.aar is dinied とか言われていますが。じゃあ無理じゃんということで、もうやめます。

ちなみに、シーンをDemosではなくて、起動時のシーンに戻しましたが、同じくディナ~い と言われましたので。もう無理です。完全にはじめからやります。

余談:

いつの間にか、USBケーブル直でできるようになりましたね!しかしなぜか2Dアプリとしてインストールされてしまいます・・・不具合はないですが、気持ち悪いです。

 

 

 

VR:Unity2019からUSB経由でMirage Soloへビルド

こんにちはKeita_Nakamori(´・ω・`)です。

今日は久々にMirage Soloをいじってみました。

というのも、2017を使っていたのですが、ウィルスバスターを入れてから、なぜかビルドできなくなってしまい、どうにも解決できなかったので暫く放置していました。

さて、今日こそ復活させようというわけです。

 

今どきはUnity Hubというものがあって、これをインストールすることによって、色んなバージョンのUnityを管理することができるようです。

せっかくですから最新のUnityバージョンをインストール使用と思います。

Unity2019.3.1.1f5のインストール

Unity Hub上からインストールしました。

このときAndroid SDK とか JDKとかNDKは同時にインストールできるようになりましたので、楽になった部分であります。

Mirage Solo用のセッティング

まず、適当に、床としてプレーンを、3Dオブジェクトとしてキューブを適当に置いておきます。

シーンの追加

build settingに入って、シーンの追加をしましょう。

プラットフォーム変更

build settingに入って、プラットフォームをアンドロイドに切り替えましょう。

Vulkanの除去

player setting >Other settingsのなかでグラフィック関係でしょうか。

Vulkan(ばるかん?)というものを使うようにセットされているのですが、これがビルド時に悪さするようで、マイナスボタンを押して除去しておきます。

会社名、プロジェクト名を入力する

頭文字は大文字で書いておきます。

XRにチェック

XRにチェックを入れて、DayDreamを追加します。

Mirage Soloへのインストール

Mirage SoloとUSBケーブルを繋ぎます。

USBが、どうとかこうとか書いていますが、つなげます。

触れなければ、つながりを維持します。

Buid and runをします。

するとapkファイルが作られます。

何事もなかったように終わるので、再度実行します。すると今度はapkファイルを作るとともにMirage Solo側で見ることができるようになるます。

これでインストールと実行をやってしまったわけですが、なぜか2Dソフト群の仲間入りをしてしまっています。この辺意味不明ですが、ちゃんと動きます。

 

以上、あとで絵とか追加しておきます。眠いので寝ます。

 

 

 

 

Python:マルチスレッド threading モジュール

どーもこんにちはKeita_Nakamori(´・ω・`)です。

最近はIoT関係で遊んでいるのですが、1つのラズパイで、複数のセンサーを扱うにはどうすればいいか考えていました。

普通のシングルスレッドで実行すると、PLCでいうところのスキャンタイムに依存することになります。

あるセンサーは高速でパルスをカウントしなければならない一方で、別のセンサーは、1秒周期でいいよとか、サンプリングタイムが全然違う場合はどうすればいいのか。

解決策として、マルチスレッドというものがあります。

それぞれのセンサーでサンプリングする関数を作って、それぞれを別々のスレッドとしてオブジェクト化して、メインスレッド内で実行するというやり方です。そうすると、それぞれのスレッドが互いに干渉することなく、あたかも2つのプログラムが同時に動いているような挙動を示します。

今回は、IOTというより、Pythonの基本なので、カテゴリーはPythonにしました。

では、やってみましょう。

まずは普通の関数を実行

まず最初に time_count()という関数を作って実行してみましょう。

1秒ごとに現在時間を出力しているだけのスクリプトです。

Pythonではthreadingモジュールから利用することができます。

結果:どうでしょう、これは普通ですよね。

次は、これをスレッド化して実行してみましょう。

最後の2行で、関数をスレッドとしてオブジェクト化し、スタートさせています。

動作は、全く一緒です。

そして、次はマルチスレッドを試してみましょう。

今度は2つのスレッドを同時に動かしてみます。

結果:さあどうでしょうか。

thread_001とthread_002をスタートして、最後に”here is script end”をするスクリプトです。

thread_001が始まった直後にthread_002もスタートしていますので、スクリプト通り、thread_001による時間カウントが5秒のところで”get up now!!”というthread_002の出力が確認できます。

さらに、スクリプトの最後の”here is script end1”はthread_002がスタートされた直後に終了しています。

メインスレッドが最後までいっても、thread_001、thread_002が終わっていなければ、プログラムは終わりません。このように、実は3つのスレッドが同時に走っているわけです。

最後に

関数をメソド化して使ってみましょう。

動作は一緒です。以上です。

IOT:速くて軽い MQTTプロトコル

こんにちは、Keita_Nakamori(´・ω・`)です。

みなさんIOTしていますか?

今日はIOTで流行っている通信プロトコルであるMQTTについてやっていこうと思います。

なぜMQTTか

OASISという規格団体において、軽い、公開、単純、簡単に使えるというコンセプトで設計されたプロトコルです。

従来のHTTPプロトコルは人と人がコンピューターを介してコミュニケーションを取ることが前提となっており、1つのコンテンツで多くの情報をやり取りしています。

しかし、IOTの場合は莫大な数のIOTデバイスと接続することになりますので、速くて軽いプロトコルである、”MQTTプロトコル”を使いこなしていく必要があります。

MQTTの特徴

すこし専門用語を出しますが、

MQTTはクライアント・サーバー間のpublish・subscribeメッセージをバイナリ(2進数)でやり取りするプロトコルです。

  • トランスポート層ではTCPをベースとます。
  • セキュリティはTLS/SSLを使用します。
  • MQTTは確実なデータ発信と重複を避けることができます。
  • 順序が決まっていてかつ可逆的な2進数情報をread/writeの両方向に対して適用されます。

MQTTの用語

peer:仲間という意味で、PCやIOTデバイスのようなサーバーではない端末のことです。MQTTクライアントとも言います。

Broker:サーバーのことです。Central MQTT BrokerとかLocal MQTT Brokerという使い方をします。

Publish:Brokerにデータを渡す。

Topic:Publishされたデータを格納する箱。encodingはutf-8。例えばAなら01000001という2進数8bitで表現されます。

Topic Level:トピックはツリー構造で格納されます。例えば

  • mytopic/machine_001/transmission_system_001/bearing_001/temperature

というように、トピックレベルセパレーターと呼ばれるスラッシュ記号で表現します。この各ディレクトリのことをトピックレベルと呼びます。

Subscribe:Broker内のTopicのデータを送ってもらうよう申し入れをします。

QoS:サービス品質 Quality of Serviceです。

レベルの低いものから

QoS_0

Publisherがメッセージを投げたらBrokerを通してSubscriberに渡す。そして、Publisherはメッセージを消す。

QoS_1

PublisherはメッセージをBrokerに投げる前に、Publisher自身がメッセージを保持する。PublisherがメッセージをBrokerに投げたら、Broker内で一旦保持してからSubscriberにわたす。渡ったらBrokerはメッセージを消して、続いてPublisherもメッセージを消す。少し複雑になりました。

QoS_2

PublisherはメッセージをBrokerに投げる前に、Publisher自身がメッセージを保持する。PublisherはメッセージをBrokerに投げたら、Broker内で一旦保持してからSubscriberにわたす。渡ったらBrokerはPUBRECをPublisherへ渡して、PUBRELが返ってきてから、Broker内のメッセージを消す。

渡ったらBrokerはメッセージを消して、PUBCOMPを渡す。

それによって、Publiserはメッセージを消す。とても長い手順を踏むことになります。

MQTTのヘッダーフォーマット

頭にヘッダー情報をつけます。ヘッダーは2バイトで構成されています。

  1. 4bitでコマンドメッセージタイプを指定します。
  2. 1bitでDUP(デュプリケート、複製)
  3. 2bitでQos Level(Quality of Service Level)
  4. 1bitでRERTAIN

これで1バイトです。

次の1バイト中最大4bitを使ってRemaining Lengthを表現します。

その次にペイロード(内容)を書いていくのですが、それはまたあとでやりましょう。

 

 

 

IOT:ラズベリーパイ パーティクルセンサー

どーもご無沙汰しております、Keita_Nakamori(´・ω・`)です。

先日、パーティクルセンサーが届きましたので、使ってみようと思います。

Particle Sensor Model PPD42NS

ヒーターで空気を温めて上昇気流を作り、光学式センサーを通過させることによって、粒子数をカウントするとのことです。なので、向きが大事です。

スペック

スペック的にPM2.5なんてのも取れそうです。

安定するまでに1分間必要と書いてあるので、スクリプトの中で”現在立ち上げ中です。”とか”カウントダウン”とかを入れてあげると良いと思います。

  • 検出可能な粒子サイズ: 1μm (minimum.)
  • 検出濃度範囲: 0~28,000 pcs/L (0~8,000pcs/0.01 CF=283mL)
  • 供給電圧: DC5V ±10% (CN1コネクタ:ピン1=GND , ピン3=+5V)
  • 作動温度範囲: 0~45°C
  • 作動湿度範囲: 相対湿度95% 以下 (結露なきこと)
  • 電力消費: 90mA
  • 周囲温度: -30~60°C
  • 安定するまでの立上時間:1分
  • 電源ONから安定に必要な時間:1分
  • 寸法: 59(W) × 45(H) × 22(D) [mm]
  • 出力方式:負論理、デジタル出力 ← ここは後で解説します。
  • Hi :  4.0V以上  Low :  0.7V以下

コネクタ

右から 黒 赤 黄 のケーブルがついた脱着可能なコネクタがついていました

しかし、これ、ブレッドボードに刺さるわけでも、ブレッドボード用のケーブルがささるわけでもないので、取っ払ってしまいました。

コネクタケーブルを引き抜くと、ちょうどラズパイのGPIOと同じサイズのピンが出てきますので黒 赤 黄の3本のメス型ケーブルに差し替えました。

説明書によると 右から

CN : S5B-EH(JST)
1 : COMMON(GND)
2 : OUTPUT(P2)
3 : INPUT(5VDC 90mA)
4 : OUTPUT(P1)
5 : INPUT(T1)・・・FOR THRESHOLD FOR [P2]

となっていますので、使用するのは、黒:GND 赤:5V 黄:出力P1 の3つになります。

ラズパイ側のGPIO

事前に必要な知識として、ラズパイGPIOピンの指定方法には2種類の表現があります。

1.BOARD番号で指定する場合

PythonではGPIO.setmode(GPIO.BOARD)と書きます。

ラズパイのボード(基盤)の配置順に番号が振られていて、たとえばpin=40とした場合はGPIO21のことを指します

2.BCM番号で指定する場合

こちらはGPIO.setmode(GPIO.BCM)と書きます。
GPIO21を指定したいときは、そのままpin=21と書きます。

こちらのほうがわかりやすいので私はこちらを使っています。どっちでもOKです。

出力データと処理の話

  • 出力はパルスで出力されます。
  • 低パルスの状態が30秒間に占める割合(LPO:Low Plulse Occupancy time)を粒子数として換算するようです。

「1μm以上の粒子が283mLの中に何個入っているか」と「低パルス占有率」の関係を測定したサンプルデータです。(メーカーHPより)

 

スクリプト

では、センサーから出力されたLowパルスの占有率を算出しましょう。

まずは、うまく行かなかった例です。

改良

動かないので、改良ついでにクラス化してみました。

なおかつ30秒ごとに出力される粒子濃度のデータをconsentration.txtに随時書き出すようにしました。

 

出力:consentration.txt

中身は下記のような感じです。

データ処理

データを処理するためにpandasで読み込んで、整えましょう。

文字パターン抽出 ” .str.extract() ” で文字列を 年月日 時間 濃度 に切り分けます。

すると、こんな感じで切れました

ymd hms ms consentration
0 2019-05-30 19:16:40.318976 0.07213182909293626
1 2019-05-30 19:17:10.434010 0.0951778309901365
2 2019-05-30 19:17:40.536987 0.07830632987722516
3 2019-05-30 19:18:10.660109 0.05319190541036891
4 2019-05-30 19:18:40.774304 0.030014825256954498
5 2019-05-30 19:19:10.876265 0.01660005851583172
6 2019-05-30 19:19:40.980323 0.019892370764988204

可視化

ざっくりとグラフを書いてみます。

なんじゃこりゃ(*´﹃`*)

でもとりあえず、なんかおかしいことは分かりました。なんで階段状なんだろう。

 

もっと研究が必要ですね。

 

IOT:ラズベリーパイでサーボドライバPCA9685を使ってみる

Keita_Nakamoriです。

前回はサーボモータSG92Rをラズパイに直結して動かしてみました。

今回はサーボモータを16個同時に動かすことができるサーボドライバPCA9685を使って、SG90とSG92Rを同時に動かしてみようと思います。

 

動画

基本スペック

  • I2C周波数範囲:24-1526Hz
  • 動作電圧:2.3-5.5V
  • 入出力の許容電圧:5.5V
  • 最大62個のPCA9685が接続できます¥。よって992個のサーボモータを同時に動かせます。

余談:I2Cはアイ スクウエア シーと呼ぶそうです。

ピン

左端のピン

は、上から

  • GND:ラズパイGIPIOのグランドに接続する
  • DE:??? どこにも繋げない
  • SCL:シリアル通信のクロック ラズパイGIPIOのSCL1に繋ぐ
  • SDA:シリアル通信のデータ   ラズパイGPIOのSDA1に繋ぐ
  • VCC:プラス電圧 ラズパイGPIOの+5Vに繋ぐ
  • V+:??? どこにも繋げない

下端のピン

はサーボモータを接続します、左から0~15番が振られてあり合計16個のサーボモータと接続できます。

上から、

  • PWM:サーボモータのPWM=オレンジ
  • V+:サーボモータの赤
  • GND:サーボモータの茶

上端のコネクタ

は、電源供給です。

  • 左はV+:ラズパイの5Vに繋ぎます
  • 右はGND:ラズパイのGNDに繋ぎます
  • 今回はラズパイのGPIOに繋ぎましたが、16個サーボモータを繋げるときは、別途電源を取らなくてはならないと思います。

制御の話

  • PCA9685はPWMで動きます。
  • パルス幅によってサーボモータの回転角が0~180degが決定されます。
    • 例えば 0.5ms幅のとき0deg、1.5ms幅のとき90deg、2.5ms幅のとき180degになったりします。(周波数で変更できます。周波数が高いほうが高速で制御できます。)
  • アナログサーボの周波数範囲は30~60Hzのものがほとんどです。
  • 例えば、周波数f=60Hzのとき周期はT=1/f=17ms です。(早い方がいいので60Hzで考えましょう。)
  • 周期Tの分解能は12bitなので、周期Tを2^12=4096分割できます。1分割分を1ステップと呼ぶことにしましょう。
  • 周期17msを4096分割できるので、1ステップあたり0.004150390625ms になります。
  • パルス幅を0.5msにしたければ、ステップは0.5/(17/4096)=120.47058823529412ステップになります。
  • サーボモータ角度をodegにしたいときは0.5msですから、120ステップをONして、残りの(4096-120)をOFFにすれば良いのです。
サーボ回転角度[deg] ONの時間 [ms]  ステップ数
0 0.5 120
60 1.0 240
90 1.5 361
120 2.0 481
180 2.5 602
  • サーボ回転角度を0degから180degにするためには、(602-120)=482ステップになります。
  • 1degあたりのステップ数は 482ステップ/180deg = 2.7 (step/deg)
  • なので任意のサーボ回転角度θでステップ数Nsを表現すると、Ns=120+2.7θ ということになります。

モジュール Adafruit_PCA9685

pip3 install Adafruit_PCA9685 したところ拒否されました。

pipのバージョンを上げて再チャレンジします。

pip3 install –upgrade pip3 と書いたところ pip3でなくてpipで書けみたいなことを言われました。

pip install –upgrade pip と書いたところ許可がないといっております。

なので、スーパーDOしてみます。

sudo pip install –upgrade pip これでOKでした

Successfully uninstalled pip-19.0.3
Successfully installed pip-19.1.1

そして再度チャレンジ

pip3 install Adafruit_PCA9685  [Errno 13] 許可がありません

なるほど読めました。やはり須藤ですね。

sudo pip3 install Adafruit_PCA9685

Successfully installed Adafruit-GPIO-1.0.3 Adafruit-PCA9685-1.0.1 adafruit-pureio-0.2.3

これでやっとAdafruit_PCA9685モジュールがインストールできました。

pip freezeすると

Adafruit-GPIO==1.0.3
Adafruit-PCA9685==1.0.1
Adafruit-PureIO==0.2.3

が入っていました。注意点として、importするときはAdafruitの後ろにはハイフンではなくアンダースコアになります。

スクリプト

余談

ラズパイの操作はWindowsマシンからrealVNC Viewerでリモートしているのですが、ラズパイ側のidleに書いたスクリプトをcnt+c しても Windows側にcnt+v できません。

コツがありまして、ラズパイ側のText Editorに一旦貼り付けた後に、それをcnt+cしてから、Windows側にcnt+v すると、しっかりと貼り付けられます。

どうぞお試しあれ。

IOT:ラズベリーパイでサーボモータSG92Rを動かす

どーもこんにちはKeita_Nakamori(´・ω・`)です。

今日は、GPIOでサーボモータを動かして見ようと思います。

デバイス

サーボモータ:SG92R

配線

  1. サーボの茶をGND(グランド)
  2. サーボの赤を電源+5V
  3. サーボのオレンジは制御パルス用なので、今回はGPIO18に接続しました。

ラズパイの電源は5Vバッテリー2.1Aです。

※サーボの挙動がガクガクしています。電源のせいかも・・・

テストスクリプト

 

IOT:ラズベリーパイにVNC接続してOpenCVで顔認識する

どーもこんにちは(´・ω・`)です。

 

前回、ラズベリーパイにVNC接続してOpenCVでカメラの起動に成功しました。

今回は更に、そのOpenCVで顔認識も追加していこうと思います。

bcm2835-v4l2 の自動化

前回ハマりました、bcm2835-v4l2 についてですが、やはりシャットダウンすると、無効になってしまい、OpenCVが機能しませんでした。

今回は、まず起動したときに自動的にbcm2835-v4l2 が実行される方法からやっていきます。

/etc/modules を開くと

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with “#” are ignored.

i2c-dev

と書いてありますが、これは”ブートするときにロードするためのカーネルモジュール群” を書いておく場所になっています。Windowsでいうとスタートアップです。

ここにbcm2835-v4l2をいれればOKなのですが、このファイルは書き込み禁止なので、予め解除しておきます。

ファイル書き込み禁止を解除する

パーミッションを確認します。

pi@pi:/etc $ ls -l modules

-rw-r–r– 1 root root 203 3月 23 20:29 modules

スーパーユーザーsudoとしてチェンジモードchmodして、パーミッションを777にします。

pi@pi:/etc $ sudo chmod 777 modules

で、変更が成功したか確認すると
pi@pi:/etc $ ls -l modules

-rwxrwxrwx 1 root root 203 3月 23 20:29 modules

フルアクセスに変更されました。

その上で、チェンジディレクトリcd /etc/でvimでmodulesを開きます。

pi@pi:/etc $ vim modules

i2c-devの下にbcm2835-v4l2を追加して保存しましょう。

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with “#” are ignored.

i2c-dev
bcm2835-v4l2

キャットで確認すれば

pi@pi:/etc $ cat modules

しっかりとbcm2835-v4l2が追加されているのがわかると思います。

本題:Opencvで顔認識をやってみる

基本的には、前回のコードに学習済みハールカスケードと顔認識した顔に四角い図形でマーキングをするスクリプトを追加するだけです。

まずhaarcascade_frontalface_alt2.xmlは/usr/local/share/OpenCV/haarcascades/ の中に入っているので、作業ディレクトリであるhome/pi/の中へコピーを作っておきます。

以上、簡単ですね。

IOT:ラズベリーパイにVNC接続してOpenCVで cv2.VideoCapture(0)してみる

どーもこんにちはKeita_Nakamori(´・ω・`)です。

今日は、WindowsマシンからラズベリーパイにVNC接続してOpenCVで cv2.VideoCapture(0)に挑戦します。

まずはrealVNC viewerを起動してIPアドレスを打ってVNC接続します。

1回つなげたことのあるIPアドレスは保存され、アイコンみたいに表示されるので2回目からはアイコンをクリックするだけの簡単操作でした。

落とし穴

早速ハマりました。cap=cv2.VideoCapture(0)してもcapにはなにもデータが入ってきません。ふぁ~(*´Д`)

ret, img = cap.read() しても、当然imgはNoneです。

なぜだ!

思い出しました

そう、かつてハマりまくった、あのときを・・・

ラズパイ専用カメラをしようしているので、一般的なwebカメラとして認識できるように下記のコードを実行することが必要でした。

注意点としては 最後の部分は 「ぶい よん える に」 です。

「ぶい よん いち に」 だと思って奮闘してしまいました。

sudo modprobe bcm2835-v4l2

ということで、shellでsudo modprobe bcm2835-v4l2と打ってカメラを認識させます。

テストコードを実行すると・・・

はい、隣の部屋のソファーが写っています。

弱点

ラズパイはwifi接続、Windowsマシンは有線ですが、VNC解像度をミディアムにしても、カメラのキャプチャー映像はガックガク!!です。

低解像度だと色がキッタナイ!

どうにもなりません。

念の為、試運転のコードを貼っておきます。

 

 

IOT:ラズベリーパイにwindowsからVNC接続

今日はSSH接続に引き続きVNC接続をやってみます。

IT予備知識

VNC

-Virtual Network Computing

仮想ネットワークコンピューティング。

サーバ側(ラズパイ)の画面をにピクセル化してクライアント(windowsマシン)へ送信しクライアント側の画面から遠隔操作することができます。

通信プロトコルはRFBプロトコルという、正にVNCのための非常に軽いプロトコルを使います。(RFB = Remote Frame Buffer)

VNCソフトウェアのインストール

RealVNCのVNC Viewerをダウンロードします。

 

起動したら、SSH接続に成功したラズパイのIPアドレスを入力します。

SSH接続と同様にIDはpi、そしてパスワードを入力します。

これだけで、ラズパイのGUIをリモートコントロールできます。

ラズパイの画面解像度の設定

しかし、ラズパイ画面の解像度が悪いので、設定します。

ラズベリーマークのアプリケーション>設定>Rasberry Piの設定>1920x1080

windows側の画面設定1920×1080に合わせました。とりあえずこの設定でやってみましょう

システムタブ>解像度>

右下のOKを押すと再起動が促されますの再起動します。

すると、一旦VNC接続が切れますが、1分位待つと再起動完了の頃合いで再び自動で接続されます。

画面上にマウスカーソルを持っていくと、なにやらVNCの画面設定がポップダウンします。歯車マークを押すとプロパティ設定が開くのでさ、General>Picture quality:をautomaticからHighに変更しました。

ScalingもAutomatic(Prewserve aspect ratio=ON)にしましたが、人によっては、若干見切れているとか調整の余地がありそうです。