3dayboy

技術備忘録

Linux で NordVPN の Mesh Network に接続する

手順

インストール

NordVPN クライアントをインストールする:

sh <(curl -sSf https://downloads.nordcdn.com/apps/linux/install.sh)
sudo usermod -aG nordvpn $USER
nordvpn login

(参考:https://meshnet.nordvpn.com/getting-started/how-to-start-using-meshnet/using-meshnet-on-linux)

初期設定

ホームネットワークのサブネット内で VPN 接続が適用されないようにする (例:subnet が 192.168.8.0/24 の場合):

nordvpn allowlist add subnet 192.168.8.0/24

メッシュネットワークを有効化する

nordvpn set meshnet on

# Check peer list
nordvpn mesh peer list

NordVPN に接続する

nordvpn connect

NordVPN Token を作成する

NordVPN Dashboard から NordVPN を手動で設定 と書かれたリンクに飛び、遷移先でトークンを発行する。

Crontab で NordVPN へのログインを自動化する

crontab -e を実行し、crontab に次のコマンドを登録する。次の例では 1 時間に 1 回、NordVPN にログインする。 <NORDVPN_TOKEN> には上の手順で作成したトークンを用いる

0 * * * * nordvpn login --token <NORDVPN_TOKEN> && nordvpn connect

Raspberry Pi 4 初期設定メモ

環境

OS: Raspibian (Raspberry Pi 4)

SSH key の作成

$ ssh-keygen -t ed25519 -f ~/.ssh/id_rsa -C "pi@raspberry"

Hostname の設定

/etc/hostname 内に hostname を記述する

ネットワーク設定

ネットワーク設定の確認

$ nmcli con show
NAME                UUID                                  TYPE      DEVICE 
Wired connection 1  59f90fc0-a46f-32be-8824-adb2c4e0c6fe  ethernet  eth0   
lo                  3d2417bd-2b05-4ffa-a331-0a7acc570543  loopback  lo     
preconfigured       535c9b2e-07d2-4809-8032-733b13b44ed2  wifi      wlan0  

Wifi の無効化

sudo nmcli con down "preconfigured"

静的 IP の付与

sudo nmcli con mod "Wired connection 1" ipv4.addresses 192.168.0.200/24
sudo nmcli con mod "Wired connection 1" ipv4.gateway 192.168.0.1
sudo nmcli con mod "Wired connection 1" ipv4.dns 192.168.0.1
sudo nmcli con mod "Wired connection 1" ipv4.method manual

# Apply configuration
sudo nmcli con down "Wired connection 1" && sudo nmcli con up "Wired connection 1"

SSH Password login の無効化

/etc/ssh/sshd_config を編集し次の設定を追加する

PasswordAuthentication no

設定を反映する

sudo systemctl restart ssh

Kotlin で .properties ファイルを1行でロードする

Kotlin を使って .properties ファイルを1行でロードしてみます。

結論

import java.io.File
import java.util.Properties

fun main() {
    val properties = Properties().apply { File(".properties").inputStream().use(this::load) }
}

解説

こちらの記事 https://qiita.com/Toshimichi/items/03ca398d7717405de695 の余談にある、3行で .propertiesを ロードするコードが原型となっています。

val properties = Properties()
val file = File(".properties")
file.inputStream().use(properties::load)

このfileという変数は、.properties をロードした後は使わないその場限りのものです。 こういう時、スコープ関数が役に立ちそうです。

スコープ関数を使って file 変数を中に閉じ込める

val properties = Properties().apply {
    val file = File(".properties")
    file.inputStream().use(this::load)
}

この apply 関数 がスコープ関数 (の一種) です。 apply 関数では、引数のクロージャ内で this を用いてレシーバを操作することができます。 返り値はそのままレシーバになるので、宣言と同時に初期操作したい場合や、初期化のための余計な変数を散らかしたくない場合に役立ちます。 スコープ関数については、 Kotlin スコープ関数 用途まとめ - Qiita が非常に分かりやすいです。

あとは、諸々整形して1行になります。

Gradle + Java のプロジェクトに Kotlin を混ぜて相互運用する

Gradle + Java で作ったアプリケーションを段階的に Kotlin でリプレイスしようと思ったので、相互運用する方法をメモ。

結論

build.gradle を kotlin プロジェクト仕様に置き換えれば ok。

build.gradle (Before; "$ gradle init --type java-application" で自動生成されるもの) :

plugins {
    id 'java'
    id 'application'
}

repositories {
    jcenter()
}

dependencies {
    implementation 'com.google.guava:guava:28.0-jre'
    testImplementation 'junit:junit:4.12'
}

application {
    mainClassName = 'abcdefg.App'
}

build.gradle (After; "$ gradle init --type kotlin-application" で自動生成されるもの) :

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.41'
    id 'application'
}

repositories {
    jcenter()
}

dependencies {
    implementation platform('org.jetbrains.kotlin:kotlin-bom')
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    testImplementation "org.jetbrains.kotlin:kotlin-test"
    testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
}

application {
    mainClassName = 'Main'
}

Kotlinソースファイルの設置場所

"src/main/java" に混在させるか、"src/main/kotlin" ディレクトリを作成してその中に入れる。 それ以外のディレクトリで管理したい場合は、以下の例のように build.gradle の sourceSet で指定する。

sourceSets {
    main.kotlin.srcDirs += 'src/main/myKotlin' //for kotlin file
    main.java.srcDirs += 'src/main/myJava' //for javafile
}

参考

対象物が視野内にあるか否かを判定する

観測者が対象物を見るとき、視野 (FOV: Field of View) の内側にあるか否かを判定する。

パラメータ

  • 観測者の視野角  0 \leq \phi \leq 360^\circ
  • 観測者の方向ベクトル  \vec{v} (向きのみに着目するので、大きさは何でもいい)
  • 観測者の位置ベクトル  \vec{x}
  • 対象物の位置ベクトル  \vec{x}'

f:id:sawa2d2:20191018130926p:plain

判定方法

次の式で求まる:

 
{\rm isInFOV}(\phi, \vec{v}, \vec{x}, \vec{x}') = 
\begin{cases}
  \rm{true} & (\cos\frac{\phi}{2} \leq \cos \theta \leq 1) \\
  \rm{false} & ({\rm otherwise})
\end{cases}, \displaystyle \cos \theta = \frac{\vec{v}\cdot (\vec{x}'-\vec{x})}{|\vec{v}||\vec{x}'-\vec{x}|}

f:id:sawa2d2:20191018131001p:plain

 cos\frac{\phi}{2} の値が  -1 なら全方面を知覚、 0 なら前方  180^\circ を知覚、 1 なら前方にまっすぐ伸びる直線上にあるものを知覚。