VS Codeでvenvがうまく動作しなくなった話

結論 venvをあきらめて、Pipenvを導入すればなぜか解決した。 経緯 Pythonの開発環境にVS Codeを使っていましたが、ある日突然、venvで作った環境が見えなくなりました。 PowerShellからは切り替えができるので、venv自体は正しく動いているようでした。 PythonとVS Codeをクリーンインストールしても状況は変わりませんでした[1]。 Pipenvの使い方 最近はPipenvというものがあるらしいので、それを導入することとしました[2][3]。 pip install pipenv 以下のように環境変数を設定することで、プロジェクトのフォルダ直下に仮想環境を構築してくれます。 PIPENV_VENV_IN_PROJECT=true VS Code上にフォルダを作成し、その直下で仮想環境を作成します。 コマンドはVS Code上のPowerShellで行いました。 例えば以下のようになります。パスやPythonのバージョンはご自身の環境に合わせてください。 *pythonの後に半角スペースがあるのでうっかり詰めないでください。 *venvファイルが作成されるという情報もありますが、私の場合はPipfileのみ作られました。 PS PS C:\Users\User Name\Documents\CODE\Python\Test> pipenv install --python 3.8 VS Code上でF1キーを押して、「reload」を検索して実行します。 これで左下のPythonのバージョンセレクトから環境選択できるはずです。 仮想環境から抜けるときは以下のコマンドを使います。 deactivate 参考文献 [1] sota0726 「VScodeを完全にアンインストールする方法(windows10)「拡張機能のホストが予期せずに終了しました。」を改善するために」閲覧日:2020/09/13 https://www.atmarkit.co.jp/ait/articles/1810/12/news026.html [2] KRiver1 「pyenv、pyenv-virtualenv、venv、Anaconda、Pipenv。私はPipenvを使う。」閲覧日:2020/09/13 h

RICHO THETAの簡単なAndroidアプリ

RICHO THETAを最初見たときは,あんまりピンと来なかったのですが使ってみると便利で面白いですね.
そんなTHETAをいじる機会があったので,簡単なAndroid用のプログラムを作ってみました.

SDKは下記のサイトからDLできます.

RICHO THETA Developpers
https://developers.theta360.com/ja/


SDKに付属しているサンプルプログラムは私にとって複雑で,何をしているのかわかりにくいものでした.
そこで,SDKのサンプルとリファレンスを頼りに,以下のようなシャッターを切るだけの簡単なサンプルを作りました.

SimpleTHETA_01

このサンプルはCONNECT Buttonを押してTHETAに接続し,SHOOT Buttonを押してシャッターを切るというプログラムです.
切断するときはDISCONNECT Buttonを押します.
THETAのステイタスからGUIを動かすサンプルとして,各操作の状況をTHETA statusというtextviewに描画しています.

それではこのプログラムの説明を行います.

まずは,以下のように,インターネットのpermissionを取ります.
この記述は,AndroidManifest.xmlに記述します.
<uses-permission android:name="android.permission.INTERNET"/>
つぎに,GUIのレイアウトを設定します.デフォルトではactivity_main.xmlに記述します.
    <LinearLayout
    android:id="@+id/linearLayout1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="28dp"
    android:layout_marginTop="64dp"
    android:orientation="vertical" >
        
        <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        
         <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="THETA status:" />    
             
         <TextView
         android:id="@+id/status"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:text="Status" />
        
        </LinearLayout>
        
        <LinearLayout
        android:id="@+id/linearLayout3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        
         <Button
         android:id="@+id/connect"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="CONNECT" />
         
         <Button
         android:id="@+id/disconnect"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="DISCONNECT" />
         
         <Button
         android:id="@+id/shoot"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="SHOOT" />
        
        </LinearLayout>
 
    </LinearLayout>

これまでで,準備が整ったのでMainActivity.javaに処理を記述します.
この処理は基本的に各ボタンのListnerを設定して,そのボタンに合わせて処理を行います.
気を付ける点は以下の2つです.
  1. THETAとのやりとりはINTERNETを使うので,AsyncTaskなどを使って別スレッドで行う.
  2. GUIを別スレッドから操作するときは,Handlerを使う.
この点だけ気を付ければ特別難しい処理はないと思います.
各ボタンを押すとConnectTask,DisConnectTask,ShootTaskが実行されます.

ConnectTaskでは,指定したIPアドレスのTHETAに接続を行い,成功したらCONNECTED,失敗したらERRORと表示します.
DisConnectTaskでは,TETAとの接続を断ち,成功したらDISCONNECTED,失敗したらエラーログを表示します.
ShootTaskでは,シャッターを切り,成功したらSHOOT,失敗したら各エラーを表示します.

public class MainActivity extends Activity {
 
 PtpipInitiator camera;
 private static final String IP_ADDRESS = "192.168.1.1";
 private TextView txt_theta_status;
 private Button btn_theta_connect;
 private Button btn_theta_disconnect;
 private Button btn_theta_shoot;
 
 private Handler handler = null;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  txt_theta_status = (TextView) findViewById(R.id.status);
  btn_theta_connect = (Button) findViewById(R.id.connect);
  btn_theta_disconnect = (Button) findViewById(R.id.disconnect);
  btn_theta_shoot = (Button) findViewById(R.id.shoot);
        
  btn_theta_connect.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
        new ConnectTask().execute();
       }
  });
        
         btn_theta_disconnect.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
        new DisConnectTask().execute();
       }
         });
        
         btn_theta_shoot.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
        new ShootTask().execute();
   }
         });
        
         handler = new Handler();
 }
 
 
 private class ConnectTask extends AsyncTask {
     @Override
     protected String doInBackground(String... params) {
         try {
             camera = new PtpipInitiator(IP_ADDRESS);
             
             handler.post(new Runnable() {
              @Override
              public void run() {
               txt_theta_status.setText("CONNECTED");
              }
             });
             
             
         } catch (Throwable e) {
             e.printStackTrace();
             
             handler.post(new Runnable() {
              @Override
              public void run() {
               txt_theta_status.setText("ERROR");
              }
             });
         }
         return null;
     }
 }
 
 private class DisConnectTask extends AsyncTask {
  @Override
  protected Boolean doInBackground(Void... params) {

   try {
    PtpipInitiator.close();
    
    handler.post(new Runnable() {
              @Override
              public void run() {
               txt_theta_status.setText("DISCONNECTED");
              }
             });
    
    return true;

   } catch (Throwable throwable) {
    final String errorLog = Log.getStackTraceString(throwable);
    handler.post(new Runnable() {
              @Override
              public void run() {
               txt_theta_status.setText(errorLog);
              }
             });

    
    return false;
   }
  }
 }

 private static enum ShootResult {
  SUCCESS, FAIL_CAMERA_DISCONNECTED, FAIL_STORE_FULL, FAIL_DEVICE_BUSY
 }
 
 private class ShootTask extends AsyncTask {

  @Override
  protected ShootResult doInBackground(Void... params) {
   try {
    PtpipInitiator camera = new PtpipInitiator(IP_ADDRESS);
    camera.initiateCapture();
    handler.post(new Runnable() {
              @Override
              public void run() {
               txt_theta_status.setText("SHOOT");
              }
             });
    return ShootResult.SUCCESS;

   } catch (IOException e) {
    handler.post(new Runnable() {
              @Override
              public void run() {
               txt_theta_status.setText("FAIL_CAMERA_DISCONNECTED");
              }
             });
    return ShootResult.FAIL_CAMERA_DISCONNECTED;
   } catch (ThetaException e) {
    if (Response.RESPONSE_CODE_STORE_FULL == e.getStatus()) {
     handler.post(new Runnable() {
               @Override
               public void run() {
                txt_theta_status.setText("FAIL_STORE_FULL");
               }
              });
     return ShootResult.FAIL_STORE_FULL;
    } else if (Response.RESPONSE_CODE_DEVICE_BUSY == e.getStatus()) {
     handler.post(new Runnable() {
               @Override
               public void run() {
                txt_theta_status.setText("FAIL_DEVICE_BUSY");
               }
              });
     return ShootResult.FAIL_DEVICE_BUSY;
    } else {
     handler.post(new Runnable() {
               @Override
               public void run() {
                txt_theta_status.setText("FAIL_CAMERA_DISCONNECTED");
               }
              });
     return ShootResult.FAIL_CAMERA_DISCONNECTED;
    }
   }
  }

 }

以上で,AndroidアプリからTHETAのシャッターを切る方法の説明を終わります.

コメント

このブログの人気の投稿

C++11のためにGCCの最新版をインストールする

分解:Logicool M570

MOCO'Sキッチンのフォントに似せるβ版