JetbotでRoad Following + Collision Avoidanceを同時に走らせた。


GitHubのcollision_avoidanceとroad_followingが更新されていました。
https://github.com/NVIDIA-AI-IOT/jetbot
どちらもResnet18を使っているので、両方の学習モデルを同時に搭載して走らせてみました。
自動走行中、コースに人形(青)が侵入!人形の運命は如何に?

動画

<衝突防止>
https://www.youtube.com/watch?v=YIbqgLoxDNM
<ラインフォロー+衝突防止>
https://www.youtube.com/watch?v=U9pHLGSxvCQ
 

準備

Road Following, Collision Avoidanceを通常どおり学習させます。
私はRoad Followingで350データ、Collision Avoidanceで各200データ入れました。

Road FollowingのフォルダにCollision Avoidanceのtrained modelを入れておく。
Road Followingフォルダでlive_demo.ipynbをコピーしこれを改造します。

live_demo-Copy1.ipynb
#途中から始めています。
device = torch.device('cuda')
model = model.to(device)
model = model.eval().half()
#ここまではオリジナル。
#ここから下記5行追加、modelcが衝突回避用モデルです。
modelc = torchvision.models.resnet18(pretrained=False)
modelc.fc = torch.nn.Linear(512, 2)

modelc.load_state_dict(torch.load('best_model_resnet18.pth'))

modelc = modelc.to(device)
modelc = modelc.eval().half()
#ここまで追加
live_demo-Copy1.ipynb
import time #この行追加しました。

angle = 0.0
angle_last = 0.0

def execute(change):
    global angle, angle_last
    image = change['new']
    xy = model(preprocess(image)).detach().float().cpu().numpy().flatten()
    x = xy[0]
    y = (0.5 - xy[1]) / 2.0

    x_slider.value = x
    y_slider.value = y

    speed_slider.value = speed_gain_slider.value

    angle = np.arctan2(x, y)
    pid = angle * steering_gain_slider.value + (angle - angle_last) * steering_dgain_slider.value
    angle_last = angle

    steering_slider.value = pid + steering_bias_slider.value


    #collision avoidance     #ここから追加です。
    x1 = preprocess(image)
    y1 = modelc(x1)

    # we apply the `softmax` function to normalize the output vector so it sums to 1 (which makes it a probability distribution)
    y1 = F.softmax(y1, dim=1)

    prob_blocked = float(y1.flatten()[0])

    #blocked_slider.value = prob_blocked

    if prob_blocked < 0.2:   #回避不要の時は、通常の制御。
        robot.left_motor.value = max(min(speed_slider.value + steering_slider.value, 1.0), 0.0)
        robot.right_motor.value = max(min(speed_slider.value - steering_slider.value, 1.0), 0.0)

    else:                   #回避制御時は停止する。
        #robot.left(0.2)
        robot.forward(0.0)
    time.sleep(0.001)          #ここまで追加。


execute({'new': camera.value})

Road Follwingの学習が荒いのと、2つモデルを走らせると制御が遅くなりました。
画面のサイズを小さくして、不要な画像を減らせばもっとすっきり走りそうです。
人形(青)は衝突回避学習済でしたが、人形(赤)は未学習、でもどちらも回避しました。
機械学習は奥が深い?