pythonでの複素数の取り扱いと極座標変換し極座標グラフへプロットしてみた

pythonでの複素数の取り扱い

研究の中でpython複素数を使うことが多々あるためまとめておきます. pythonでは複素数は簡単に取り扱うことが可能である.

虚数単位をjで表す.(Not i)

c = 2 + 5j

以上です

複素数極座標変換

cmath.polar()を使うと(絶対値, 偏角)のタプルでまとめて取得が可能です.

c = 2 + 1j

print(cmath.polar(c))

極座標変換したものを極座標グラフへ

import numpy as np
import matplotlib.pyplot as plt
import cmath

c =11618.669889921717+7.8985760292917565e-19j

print(cmath.polar(c))
plt.polar(cmath.polar(c)) # 極座標グラフのプロット

plt.show()

f:id:kobakenkken:20181103232527p:plain

参考

(62) 直交座標 to 極座標変換 – Pythonやってみる!

note.nkmk.me

Google ColabでKaggle! 【STEP1: Kaggle APIの設定とか】

Google Colabを起動

自分のGoogleアカウントからGoogle Colabを起動して開いて下さい

Google Drive>新規>その他>Colaboratory

kaggle APIのインストール

!pip install kaggle

Kaggle API Keyをダウンロードする

Kaggleを開いて自分のアカウントページを開く

アドレスのサンプル https://www.kaggle.com//account

Create New API Token をクリック kaggle.json をダウンロード

Google Colabへkaggle.jsonをアップロード

from google.colab import files
files.upload()

アップロード完了後、kaggle.jsonを移動する

!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle/

参考

https://stackoverflow.com/questions/49310470/using-kaggle-datasets-into-google-colab

https://colab.research.google.com/drive/1DofKEdQYaXmDWBzuResXWWvxhLgDeVyl?pli=1&authuser=2

以上 次回は実際の推測や提出までです

KerasでCNNの中間層の可視化(特徴マップ)や重みの可視化まとめ

kerasで中間層の出力を取得

kerasでCNNの中間層を取得する方法は2種類存在する.

ケース1

from keras.models import Model

intermediante_layer_model = Model(inputs=model.input, outputs=model.get_layer("fc2").output)
y = intermediante_layer_model.predict(X)
print(y.shape)

ケース2

from keras import backend as K

get_layer_output = K.function([model.layers[0].input],[model.layers[21].output])
y = get_layer_output([X,0])[0]
print(y.shape)

ソースコードfeaturemap.py

中間層の重みを可視化

中間層の重みを可視化するためには上記の中間層の取得のときに使ったコードを利用する.

weights = resnet.get_layer("conv1").get_weights()[0]

ソースコード

from keras.applications import ResNet50
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
<200b>
resnet = ResNet50()
resnet.summary()
<200b>
weights = resnet.get_layer("conv1").get_weights()[0]
<200b>
<200b>
weights.shape
print("shape",weights.shape)
<200b>
w = weights[:, :, ::-1, 0].copy()
m = w.min()
M = w.max()
w = (w-m)/(M-m)
plt.imshow(w)
<200b>
result = Image.new("RGB", (7*8+(8-1), 7*8+(8-1)))
for i in range(64):
    w= weights[:, :, ::-1, i].copy()
    M = w.max()
    m = w.min()
    w = (w-m)/(M-m)
    w *= 255
    img = Image.fromarray(w.astype("uint8"), mode="RGB")
    result.paste(img, (7*(i//8) + (i//8), 7*(i%8)+(i%8)))
plt.imshow(result)

f:id:kobakenkken:20181023130105p:plain

激安ラジコン(RC)の自動運転化計画※RCをEV3に変更しました

目的:ラジコンの自動運転をすること

使ったもの

ハード

  • ラジコン:レゴ® マインドストーム® EV3
  • ラズベリーパイ3
  • カメラ:LOGICOOL C270
  • ソフト
  • 言語:python
  • DLライブラリ:Keras(on Tensorflow)
  • その他:Opencv,numpy,paho-mqtt...
  • システムの概要

    今回用いたコースはこちら

    今回は言語をpython限定.

    行動の分類を線の数を考慮したクラス分類問題とした f:id:kobakenkken:20180624180334p:plain

     

  • RCの行動の種類
  • 前(forward),右(right),少し右(little right),左(left),少し左(little left),その他(other)の6種類

    画像転送部分(動画の配信)

    • MJPG-streamerを使ってwebカメラから取得した画像をストリーミングを行う.

    *設定

    fps:5

    width:640

    height:480

    *コマンド

    ./mjpg_streamer -i "./input_uvc.so -f 10 -r 320x240 -d /dev/video0 -y -n" -o "./output_http.so -w ./www -p 8080"
    

    モータ制御部分

    • EV3の二つのモータの制御を行う.サーバ(PC)側の分類結果からそれに対応する制御信号をMQTTにより受信し,モータの駆動させる. *プログラム

    学習・検証部分

    • KerasによりCNN部分の実装を行う. *プログラム
    #coding:utf-8
    import os
    from keras.applications.vgg16 import VGG16
    from keras.preprocessing.image import ImageDataGenerator
    from keras.models import Sequential, Model
    from keras.layers import Input, Activation, Dropout, Flatten, Dense
    from keras.preprocessing.image import ImageDataGenerator
    from keras import optimizers
    import numpy as np
    
    classes = ['foward_1', 'foward_2', 'left_1', 'left_2', 'right_1', 'right_2', 'other']
    
    batch_size = 32
    nb_classes = len(classes)
    
    img_rows, img_cols = 150, 150
    channels = 3
    
    train_data_dir = 'data/train'
    validation_data_dir = 'data/test'
    nb_train_samples = 1699
    nb_val_samples = 447
    nb_epoch = 100
    
    result_dir = 'results'
    if not os.path.exists(result_dir):
    os.mkdir(result_dir)
    
    
    if __name__ == '__main__':
    # VGG16モデルと学習済み重みをロード
    # Fully-connected層(FC)はいらないのでinclude_top=False)
    input_tensor = Input(shape=(img_rows, img_cols, 3))
    vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
    # vgg16.summary()
    
    # FC層を構築
    # Flattenへの入力指定はバッチ数を除く
    top_model = Sequential()
    top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
    top_model.add(Dense(256, activation='relu'))
    top_model.add(Dropout(0.5))
    top_model.add(Dense(nb_classes, activation='softmax'))
    
    # 学習済みのFC層の重みをロード
    # top_model.load_weights(os.path.join(result_dir, 'bottleneck_fc_model.h5'))
    
    # VGG16とFCを接続
    model = Model(input=vgg16.input, output=top_model(vgg16.output))
    
    # 最後のconv層の直前までの層をfreeze
    for layer in model.layers[:15]:
    layer.trainable = False
    
    # Fine-tuningのときはSGDの方がよい?
    model.compile(loss='categorical_crossentropy',
    optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
    metrics=['accuracy'])
    
    # train_datagen = ImageDataGenerator(featurewise_center=False,
    # samplewise_center=False,
    # featurewise_std_normalization=False,
    # samplewise_std_normalization=False,
    # zca_whitening=False,
    # rotation_range=0.2,
    # width_shift_range=0.2,
    # height_shift_range=0.2,
    # shear_range=0.2,
    # zoom_range=0.2,
    # channel_shift_range=0.1,
    # fill_mode='nearest',
    # cval=0.,
    # horizontal_flip=True,
    # vertical_flip=True,
    # rescale=None)
    
    train_datagen = ImageDataGenerator(featurewise_center=False,
    samplewise_center=False,
    featurewise_std_normalization=False,
    samplewise_std_normalization=False,
    zca_whitening=False,
    rotation_range=0.1,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    channel_shift_range=0.1,
    fill_mode='nearest',
    rescale=None)
    
    test_datagen = ImageDataGenerator()
    
    train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_rows, img_cols),
    color_mode='rgb',
    classes=classes,
    class_mode='categorical',
    batch_size=batch_size,
    shuffle=True)
    
    validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_rows, img_cols),
    color_mode='rgb',
    classes=classes,
    class_mode='categorical',
    batch_size=batch_size,
    shuffle=True)
    
    # Fine-tuning
    history = model.fit_generator(
    train_generator,
    samples_per_epoch=nb_train_samples,
    nb_epoch=nb_epoch,
    validation_data=validation_generator,
    nb_val_samples=nb_val_samples)
    
    model.save_weights(os.path.join(result_dir, '20180802.h5'))
    save_history(history, os.path.join(result_dir, '20180802.txt'))
    
    • 使用したCNNモデル:

     

    走行テスト部分

    *ラズベリーパイ3

    webカメラから動画のストリーミングを行う.

     
    

    *サーバ

    ストリーミングされた動画をキャプチャし,その画像を学習済モデルへ入力し分類を行う.その分類結果をMQTTを用いてモータの制御信号を送信する.

     
    
    #!/usr/bin/env python#!/usr/bin/env python#coding:utf-8import cv2import matplotlib.pyplot as pltfrom IPython import display
    import numpy as npfrom io import BytesIOfrom PIL import Imagefrom PIL import ImageOps
    from keras.applications.vgg16 import VGG16, preprocess_input, decode_predictionsfrom keras.preprocessing import imageimport time
    
    import socketimport numpy as npimport cv2#for predictionimport osimport sysfrom keras.applications.vgg16 import VGG16from keras.models import Sequential, Modelfrom keras.layers import Input, Activation, Dropout, Flatten, Densefrom keras.preprocessing import image
    import paho.mqtt.client as mqttimport threading# Load VGG16#model = VGG16(weights='imagenet')result_dir = 'results'classes = ['foward_1', 'foward_2', 'left_1', 'left_2', 'right_1', 'right_2', 'other']
    nb_classes = len(classes)
    img_height, img_width = 150, 150channels = 3
    pre_count = []
    
    # VGG16input_tensor = Input(shape=(img_height, img_width, channels))vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
    # FCfc = Sequential()fc.add(Flatten(input_shape=vgg16.output_shape[1:]))fc.add(Dense(256, activation='relu'))fc.add(Dropout(0.5))fc.add(Dense(nb_classes, activation='softmax'))
                # VGG16とFCを接続model = Model(input=vgg16.input, output=fc(vgg16.output))
                # 学習済みの重みをロードmodel.load_weights(os.path.join(result_dir, '20180803_3.h5'))
    model.compile(loss='categorical_crossentropy',                          optimizer='adam',                          metrics=['accuracy'])
    URL = "http://192.168.0.4:8080/?action=stream"vc = cv2.VideoCapture(URL)#///////////////////////////////////////////////////////////
    def cap (frame, client):    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)    # makes the blues image look real colored    #webcam_preview.set_data(frame)    plt.draw()    # display.clear_output(wait=True)    # display.display(plt.gcf())    plt.pause(0.01)    img = Image.fromarray(np.uint8(frame))    img = img.resize((150, 150))    x = image.img_to_array(img)    pred_data = np.expand_dims(x, axis=0)    #print("show")    plt.imshow(img)    #plt.show()
        # print("[------------------------ PREDICT ------------------------]\n")    # preds = model.predict(preprocess_input(pred_data))    # #time.sleep(1)    # #print(preds)    # results = decode_predictions(preds, top=1)[0]    # for result in results:    #     #print(result)    #     if results[0] == "[n03814639]"  or "[n03483316]":    #         print("s")    #     print("[{}] {:<30} {}%".format(result[0c], result[1],round(result[2]*100, 2)))    pred = model.predict(pred_data)[0]    #print(type(int(pred.argsort()[-1:][::-1])))    #from pynput.keyboard import Key, Listener    #print("pre_count",len(pre_count))    # host = '192.168.0.18'    # port = 1883    # keepalive = 60    # topic = 'topic/moter/dt'    # client = mqtt.Client()    # client.connect(host, port, keepalive)
        if int(pred.argsort()[-1:][::-1]) == 0:        print('foward_1')        client.publish(topic, str(310) + "," + str(300))        #time.sleep(0.2)        #client.publish(topic, str(0) + "," + str(0))
        elif int(pred.argsort()[-1:][::-1]) == 1:        print('foward_2')        client.publish(topic, str(410) + "," + str(400))        #time.sleep(0.2)        #client.publish(topic, str(0) + "," + str(0))
        elif int(pred.argsort()[-1:][::-1]) == 2:        print('left_1')        client.publish(topic, str(500) + "," + str(200))        #time.sleep(0.2)        # client.publish(topic, str(40) + "," + str(50))        # time.sleep(0.7)        # client.publish(topic, str(60) + "," + str(25))        # time.sleep(0.3)        #client.publish(topic, str(0) + "," + str(0))
        elif int(pred.argsort()[-1:][::-1]) == 3:        print('left_2')        client.publish(topic, str(300) + "," + str(200))        #time.sleep(0.2)        # client.publish(topic, str(40) + "," + str(50))        # time.sleep(0.7)        # client.publish(topic, str(60) + "," + str(25))        # time.sleep(0.3)        #client.publish(topic, str(0) + "," + str(0))
        elif int(pred.argsort()[-1:][::-1]) == 4:        print('right_1')        client.publish(topic, str(200) + "," + str(500))        #time.sleep(0.2)        # client.publish(topic, str(50) + "," + str(40))        # time.sleep(0.7)        # client.publish(topic, str(25) + "," + str(60))        # time.sleep(0.3)        #client.publish(topic, str(0) + "," + str(0))
        elif int(pred.argsort()[-1:][::-1]) == 5:        print('right_2')        client.publish(topic, str(200) + "," + str(300))        #time.sleep(0.2)        # client.publish(topic, str(50) + "," + str(40))        # time.sleep(0.7)        # client.publish(topic, str(25) + "," + str(60))        # time.sleep(0.3)        #client.publish(topic, str(0) + "," + str(0))
        elif int(pred.argsort()[-1:][::-1]) == 6:        print('other')        client.publish(topic, str(-200) + "," + str(300))
        #予測確率が高いトップ5を出力    top = 3    top_indices = pred.argsort()[-top:][::-1]    result = [(classes[i], pred[i]) for i in top_indices]    print(result)    print("")
    
    
    #///////////////////////////////////////////////////////# while True:#     ret, img = vc.read()#     cv2.imshow("Stream Video",img)#     print(img.shape)
    # Capture webcamera photo# vc = cv2.VideoCapture(0)
    
    host = '192.168.0.17'port = 1883keepalive = 60topic = 'topic/motor/dt'client = mqtt.Client()client.connect(host, port, keepalive)
    
    
    if vc.isOpened(): # try to get the first frame    is_capturing, frame = vc.read()    #cv2.imshow("Stream Video",frame)    #frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)    # makes the blues image look real colored    #webcam_preview = plt.imshow(frame)    else:    is_capturing = False
    # Push ■ Button!!while is_capturing:    try:    # Lookout for a keyboardInterrupt to stop the script        #print("pre")        # time.sleep(3)        is_capturing, frame = vc.read()        pre_count.append(1)        if int(len(pre_count)) % 5 == 0:            # thread = threading.Thread(target=cap, args=(frame,))            # thread.start()            cap(frame, client)            # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)    # makes the blues image look real colored            # #webcam_preview.set_data(frame)            # plt.draw()            # # display.clear_output(wait=True)            # # display.display(plt.gcf())            # #plt.pause(0.01)            # img = Image.fromarray(np.uint8(frame))            # img = img.resize((150, 150))            # x = image.img_to_array(img)            # pred_data = np.expand_dims(x, axis=0)            # print("show")            # plt.imshow(img)            # # plt.show()
                # # print("[------------------------ PREDICT ------------------------]\n")            # # preds = model.predict(preprocess_input(pred_data))            # # #time.sleep(1)            # # #print(preds)            # # results = decode_predictions(preds, top=1)[0]            # # for result in results:            # #     #print(result)            # #     if results[0] == "[n03814639]"  or "[n03483316]":            # #         print("s")            # #     print("[{}] {:<30} {}%".format(result[0c], result[1],round(result[2]*100, 2)))            # pred = model.predict(pred_data)[0]            # #print(type(int(pred.argsort()[-1:][::-1])))            # #from pynput.keyboard import Key, Listener            # print("pre_count",len(pre_count))            # # host = '192.168.0.18'            # # port = 1883            # # keepalive = 60            # # topic = 'topic/moter/dt'            # # client = mqtt.Client()            # # client.connect(host, port, keepalive)
                # if int(pred.argsort()[-1:][::-1]) == 0:            #     print('foward_1')            #     host = '192.168.0.17'            #     port = 1883            #     keepalive = 60            #     topic = 'topic/motor/dt'            #     client = mqtt.Client()            #     client.connect(host, port, keepalive)            #     client.publish(topic, str(200) + "," + str(200))            #     #time.sleep(0.2)            #     #client.publish(topic, str(0) + "," + str(0))
                # elif int(pred.argsort()[-1:][::-1]) == 1:            #     print('foward_2')            #     host = '192.168.0.17'            #     port = 1883            #     keepalive = 60            #     topic = 'topic/motor/dt'            #     client = mqtt.Client()            #     client.connect(host, port, keepalive)            #     client.publish(topic, str(200) + "," + str(200))            #     #time.sleep(0.2)            #     #client.publish(topic, str(0) + "," + str(0))
                # elif int(pred.argsort()[-1:][::-1]) == 2:            #     print('left_1')            #     host = '192.168.0.17'            #     port = 1883            #     keepalive = 60            #     topic = 'topic/motor/dt'            #     client = mqtt.Client()            #     client.connect(host, port, keepalive)            #     client.publish(topic, str(300) + "," + str(100))            #     #time.sleep(0.2)            #     # client.publish(topic, str(40) + "," + str(50))            #     # time.sleep(0.7)            #     # client.publish(topic, str(60) + "," + str(25))            #     # time.sleep(0.3)            #     #client.publish(topic, str(0) + "," + str(0))
                # elif int(pred.argsort()[-1:][::-1]) == 3:            #     print('left_2')            #     host = '192.168.0.17'            #     port = 1883            #     keepalive = 60            #     topic = 'topic/motor/dt'            #     client = mqtt.Client()            #     client.connect(host, port, keepalive)            #     client.publish(topic, str(200) + "," + str(50))            #     #time.sleep(0.2)            #     # client.publish(topic, str(40) + "," + str(50))            #     # time.sleep(0.7)            #     # client.publish(topic, str(60) + "," + str(25))            #     # time.sleep(0.3)            #     #client.publish(topic, str(0) + "," + str(0))
                # elif int(pred.argsort()[-1:][::-1]) == 4:            #     print('right_1')            #     host = '192.168.0.17'            #     port = 1883            #     keepalive = 60            #     topic = 'topic/motor/dt'            #     client = mqtt.Client()            #     client.connect(host, port, keepalive)            #     client.publish(topic, str(100) + "," + str(300))            #     #time.sleep(0.2)            #     # client.publish(topic, str(50) + "," + str(40))            #     # time.sleep(0.7)            #     # client.publish(topic, str(25) + "," + str(60))            #     # time.sleep(0.3)            #     #client.publish(topic, str(0) + "," + str(0))
                # elif int(pred.argsort()[-1:][::-1]) == 5:            #     print('right_2')            #     host = '192.168.0.17'            #     port = 1883            #     keepalive = 60            #     topic = 'topic/motor/dt'            #     client = mqtt.Client()            #     client.connect(host, port, keepalive)            #     client.publish(topic, str(50) + "," + str(200))            #     #time.sleep(0.2)            #     # client.publish(topic, str(50) + "," + str(40))            #     # time.sleep(0.7)            #     # client.publish(topic, str(25) + "," + str(60))            #     # time.sleep(0.3)            #     #client.publish(topic, str(0) + "," + str(0))
                # elif int(pred.argsort()[-1:][::-1]) == 6:            #     print('other')            #     host = '192.168.0.17'            #     port = 1883            #     keepalive = 60            #     topic = 'topic/motor/dt'            #     client = mqtt.Client()            #     client.connect(host, port, keepalive)            #     client.publish(topic, str(200) + "," + str(50))
    
    
                #import paho.mqtt.client as mqtt            #from pynput.keyboard import Key, Listener
                # host = '192.168.0.7'            # port = 1883            # keepalive = 60            # topic = 'mqtt/test'            # client = mqtt.Client()            # client.connect(host, port, keepalive)
                # if classes[i] == 'foward':            #     print('foward')            #     #client.publish(topic, str(0.5) + "," + str(0) + "," + str(0) + "," + str(0))            # elif classes[i] == 'right':            #     print('right')            #     #client.publish(topic, str(0.5) + "," + str(0) + "," + str(0) + "," + str(0))            # elif classes[i] == 'left':            #     print('left')                #client.publish(topic, str(0.5) + "," + str(0) + "," + str(0) + "," + str(0))                #client.publish(topic, str(0.5) + "," + str(0) + "," + str(0) + "," + str(0))
    
            # the pause time is = 1 / frameratef
        except KeyboardInterrupt:        vc.release()        is_capturing = False
    

    *EV3

    受信した制御信号をモータへ反映し,モータを駆動させ制御を行う.

     
    
    # !/usr/bin/env python3
    import paho.mqtt.client as mqtt
    from ev3dev.auto import *
    
    count = []
    
    ma = Motor('outA')
    md = Motor('outD')
    
    def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
    client.subscribe("topic/motor/dt")
    
    
    def on_message(client, userdata, msg):
    msg_str = msg.payload.decode("utf-8")
    msg_array = msg_str.split(",")
    ma.speed_sp = msg_array[0]
    md.speed_sp = msg_array[1]
    count.append(1)
    print(len(count))
    print(msg_array)
    #ma.duty_cycle_sp = msg_array[0]
    #time.sleep(3)
    #ma.stop()
    #md.duty_cycle_sp = msg_array[1]
    # time.sleep(3)
    #ma.stop()
    ma.run_timed(time_sp=250,speed_sp=ma.speed_sp,stop_action='brake')
    md.run_timed(time_sp=250,speed_sp=md.speed_sp,stop_action='brake')
    #time.sleep(1)
    
    client = mqtt.Client()
    client.connect("192.168.0.17" ,1883 ,60)
    
    client.on_connect = on_connect
    client.on_message = on_message
    
    ma.run_direct()
    md.run_direct()
    ma.duty_cycle_sp = 0
    md.duty_cycle_sp = 0
    
    client.loop_forever()
    

    実際の走行動画

    結果・考察

    激安ラジコン(RC)の自動運転化計画※プログラムは6/25掲載予定

    目的:総計1万円でラジコンの自動運転化をすること

    使ったもの

    ハード

  • ラジコン:軽トラRC(Amazon CAPTCHA
  • ラズベリーパイ
  • モータードライバー:L298n
  • カメラ:LOGICOOL C270
  • ソフト
  • 言語:python
  • DLライブラリ:Keras(on Tensorflow)
  • Opencv,numpy,paho-mqtt...

    システムの概要

    今回は言語をpython限定にした. f:id:kobakenkken:20180624180334p:plain

  • RCの行動の種類
  • 前,右,少し右,左,少し左の5種類

    画像転送部分

    • Opencvwebカメラから取得した画像をsocket通信によりサーバ側(PC)へ転送を行う.今回はUDP及びデータを圧縮した. *プログラム

    モータ制御部分

    • L298nによりモータの制御を行う.サーバ(PC)側の分類結果からそれに対応する制御信号をMQTTにより受信し,モータの駆動させる. *プログラム

    学習・検証部分

    • KerasによりCNN部分の実装を行う. *プログラム
    • 使用したCNNモデル:vgg16(転移学習)

    結果・考察

    全体として1万円以内に収めることができた. しかし、画像の転送部分での課題があり,Picamera及びffmpeg等でストリーミングを行うことで解決する予定である.

    L298Nを使ってモータの制御

    L298Nとは


    2つのモータを独立して駆動でき、正転逆転制御などに最適です。 制御は各モーターに対して、イネーブル(回転する/しない)と回転方向の指定を2線でおこないます。 マイコンでの制御のほか、スイッチなどによってマニュアル制御も簡単におこなえます。

    L298N使用 2Aデュアルモーターコントローラー: マイコン関連 秋月電子通商 電子部品 ネット通販

    http://akizukidenshi.com/catalog/g/gM-06680/   f:id:kobakenkken:20180515171831p:plain

    Pin Description

    • ENA Motor A Speed Control

    • IN1 Motor A Direction Pin 1

    • IN2 Motor A Direction Pin 2

    • IN3 Motor B Direction Pin 1

    • IN4 Motor B Direction Pin 2

    • ENB Motor B Speed Control

    Terminal Description

    • VMS 5-35V Input

    • GND 0V

    • 5V 5V input/output

    • OUT1 Motor A

    • OUT2 Motor A

    • OUT3 Motor B

    • OUT4 Motor B

    RaspiとPythonによるモータ制御

    import RPi.GPIO as gpio
    import time
     
    def init():
     gpio.setmode(gpio.BCM)
     gpio.setup(17, gpio.OUT)
     gpio.setup(22, gpio.OUT)
     gpio.setup(23, gpio.OUT)
     gpio.setup(24, gpio.OUT)
     
    def forward(tf):
     init()
     gpio.output(17, True)
     gpio.output(22, False)
     gpio.output(23, True) 
     gpio.output(24, False)
     time.sleep(tf)
     gpio.cleanup()
     
    def reverse(tf):
     init()
     gpio.output(17, False)
     gpio.output(22, True)
     gpio.output(23, False) 
     gpio.output(24, True)
     time.sleep(tf)
     gpio.cleanup()
     
    print "forward"
    forward(4)
    print "backward"
    reverse(2)
    
    #!/usr/bin/python3.4
    #MKerbachi November 6th, 2015
    #Python code to control two motors with Rpi A+ with the H bridge l298n
    
    import RPi.GPIO as GPIO # always needed with RPi.GPIO  
    import time
    import curses
    
    
    # get the curses screen window
    screen = curses.initscr()
     
    # turn off input echoing
    curses.noecho()
     
    # respond to keys immediately (don't wait for enter)
    curses.cbreak()
     
    # map arrow keys to special values
    screen.keypad(True)
    
    
    
    #If the two GND (PI + l298n) are not interconnected that won't work !
    #For all Keyboard symbols:
    #https://docs.python.org/2/library/curses.html
      
    GPIO.setmode(GPIO.BCM)  # choose BCM or BOARD numbering schemes. I use BCM  
    
    #################################################################
    #          Variables               #
    #################################################################
    
    #For Motor #1
    GPIO.setup(18, GPIO.OUT)# set GPIO 01 as an output Enabler
    GPIO.setup(24, GPIO.OUT)# set GPIO 05 as an output.
    GPIO.setup(23, GPIO.OUT)# set GPIO 04 as an output.
      
    p24 = GPIO.PWM(24, 100)
    p23 = GPIO.PWM(23, 100)
    p18 = GPIO.PWM(18, 100)    # create an object p for PWM on port 18 at 50 Hertz
                            # you can have more than one of these, but they need
                            # different names for each port
                            # e.g. p1, p2, motor, servo1 etc.
    
    #For Motor #2
    GPIO.setup(13, GPIO.OUT)# set GPIO 03 as an output Enabler
    GPIO.setup(27, GPIO.OUT)# set GPIO 02 as an output.
    GPIO.setup(17, GPIO.OUT)# set GPIO 0  as an output.
    
    p27 = GPIO.PWM(27, 100)
    p17 = GPIO.PWM(17, 100)
    p13 = GPIO.PWM(13, 100)    # create an object p for PWM on port 18 at 50 Hertz  
                            # you can have more than one of these, but they need  
                            # different names for each port   
                            # e.g. p1, p2, motor, servo1 etc.  
    
    LastKey = ""
    
    #################################################################
    #          Functions               #
    #################################################################
    
    def Stop():
                p18.start(0)
                p23.start(0)
                p24.start(0)
    
                p13.start(0)
                p27.start(0)
                p17.start(0)
                time.sleep(0.3)
                #GPIO.cleanup()
                print ("Stop executed")
                #exit()
    
    def Left():
                if LastKey != 'left' : Stop()
                p18.start(60)
                p23.start(0)
                p24.start(100)
    
                time.sleep(0.4)
                p13.start(60)
                p27.start(0)
                p17.start(100)
    
    #            time.sleep(0.3)
                #Stop()
    
    def Right():
                if LastKey != 'right' : Stop()
                p18.start(60)
                p23.start(100)
                p24.start(0)
    
                time.sleep(0.4)
                p13.start(60)
                p27.start(100)
                p17.start(0)
    
    #            time.sleep(0.3)
                #Stop()
    
    def Up():
                #if LastKey != 'up' : Stop()
                p18.start(60)
                p23.start(100)
                p24.start(0)
    
                time.sleep(0.3)
                p13.start(60)
                p27.start(0)
                p17.start(100)
    
                time.sleep(0.3)
                #Stop()
    
    def Down():
                #if LastKey != 'down' : Stop()
                p18.start(60)
                p23.start(0)
                p24.start(100)
    
                time.sleep(0.3)
                p13.start(60)
                p27.start(100)
                p17.start(0)
    
                time.sleep(0.3)
                #Stop()
    
    
    try:
        while True:
            char = screen.getch()
            print ('you entred')
            print (char)
            if char == ord('q'):
                break
            #elif char == curses.KEY_ENTER:
            elif char == ord(' '):
                # print doesn't work with curses, use addstr instead
                #screen.addstr(0, 0, 'right')
                if not ( LastKey == "enter" ) : print ('Last key was not Enter, it was %s \n' % LastKey)
                LastKey="enter"
                print ('enter\n')
                Stop()
    
            elif char == curses.KEY_RIGHT:
                # print doesn't work with curses, use addstr instead
                #screen.addstr(0, 0, 'right')
                if not ( LastKey == "right" ) : print ('Last key was not right, it was %s \n' % LastKey)
                LastKey="right"
                print ('right\n')
                Right() 
               
            elif char == curses.KEY_LEFT:
                #screen.addstr(0, 0, 'left ')       
                if not ( LastKey == "left" ) : print ('Last key was not left, it was %s \n' % LastKey)
                LastKey="left"
                print ('left\n')
                Left()
    
            elif char == curses.KEY_UP:
                #screen.addstr(0, 0, 'up   ')       
                if not ( LastKey == "up" ) : print ('Last key was not up, it was %s \n' % LastKey)
                LastKey="up"
                print ('up\n')
                Up()
    
            elif char == curses.KEY_DOWN:
                #screen.addstr(0, 0, 'down ')
                if not ( LastKey == "down" ) : print ('Last key was not down t was %s \n' % LastKey)
                LastKey="down"
                print ('down\n')
                Down()
            else:
                print ('Nothing Entred!\n')
    
    finally:
        # shut down cleanly 
        print ('In the finally section now')
        curses.nocbreak(); screen.keypad(0); curses.echo()
        curses.endwin()
        p13.stop()                # stop the PWM output
        p17.stop()
        p27.stop()
    
        p23.stop()                # stop the PWM output
        p24.stop()
        p18.stop()
    
        GPIO.cleanup()          # when your program exits, tidy up after yours
    
    
    
    
    p13.stop()                # stop the PWM output  
    p17.stop()
    p27.stop()
      
    p23.stop()                # stop the PWM output  
    p24.stop()
    p18.stop()
    
    GPIO.cleanup()          # when your program exits, tidy up after yours
    

    メモ

    アナログ出力では周波数とデューティ比を指定して、モータ制御などに使うPWM制御ができます。

    まずピンに対して周波数を設定してpwmオブジェクトを取得します。

    pwm = GPIO.PWM([チャンネル], [周波数(Hz)]) 次にpwmオブジェクトに対してデューティ比を指定して出力を開始します。

    pwm.start([デューティ比]) 例えば、ピン18に周波数1KHz、デューティ比50%でPWM出力する場合は以下のように書きます。

    pwm = GPIO.PWM(18, 1000) pwm.start(50) 途中で周波数を変更する場合は以下の関数を使用します。

    pwm.ChangeFrequency([周波数(Hz)]) 途中でデューティ比を変更する場合は以下の関数を使用します。

    pwm.ChangeDutyCycle([デューティ比]) PWM出力を停止する場合は以下の関数を実行します。

    pwm.stop() スクリプト終了時にはちゃんと停止しておきましょう。