WeChatアプレットを実現したラズベリーパイ乗用車制御


この文章は前のページの「木莓パイ小車制御プログラム」に基づいて改造したものです。主にWeChatアプリの開発も練習しました。ここでは主要コードのセグメントを簡単に記録します。多くのピットを通りました。例えば、微信小プログラムはフルスクリーンをサポートしていません。微信小プログラムは横スクリーンで展示できません。だから開発にも非常手段が使われました。これは基本的なデモと言えるので、カメラのモニタipやページの元素の位置付けには書き込み値が使われています。特にインタフェースはiPhone 6の上で実験しただけですので、他の携帯に変えたら、インタフェースが変わります。
1.基本的な考え方
  • 小さなプログラムに入るとindexページが表示され、ユーザーにサービス端末url(前のページをシミュレーションしてブラウザでget要求を取得する)
  • を入力させることができる。
  • はその後、実際の小型車コントロールインターフェースにジャンプし、ボタンをクリックすることで小型車制御
  • を実現することができます。
  • は、小車の移動を制御し、主にcontrol.jsにインターフェースボタンイベントの応答を定義し、イベントに応答する過程でhttp要求の送信を実現する。
  • indexページは以下の通りです 

    入ってからのページは次の通りです。(中の空白のところにカメラの監視カメラがありますが、起動していないので、見えません。)

    2.コード構造は以下の通りです。
    ここで、indexはトップページで、controlはコントロールページで、resディレクトリの下に保存されているのは写真リソースです。

    3.indexディレクトリ
    index.js
    
    //index.js
    //      
    const app = getApp()
     
    Page({
     data: {
     logo: "/res/rasp-logo.png",
     welcome: "        ",
     enterBtn: "  ",
     PromoteMsg: "Please enter the server address (eg: http://x.x.x.x:8080)",
     reqURL: ""
     },
     //                    
     getURL: function (e) {
     this.setData({
     reqURL: e.detail.value
     })
     },
     enterClicked: function (e) {
     /*
     *        ,       :
     * 1.                          
     * 2.          GET  ,           
     * 3.          
     */
     console.log(this.data.reqURL)
     
     if (this.data.reqURL == '') {
     wx.showModal({
     title: '  ',
     content: '            !',
     })
     return
     }
     
     //        GET  
     wx.request({
     url: this.data.reqURL,
     success: function (res) {
     //      POST    ,       ,         , control    
     console.log(res.data.match(/url = \"(\S*)\"/)[1])
     console.log(res.data.match(/src=\"(\S*)\"/)[1])
     app.globalData.postURL = res.data.match(/url = \"(\S*)\"/)[1]
     app.globalData.cameraURL = res.data.match(/src=\"(\S*)\"/)[1]
     
     //    control  
     wx.navigateTo({
      url: '/pages/control/control',
     })
     },
     fail: function(res) {
     wx.showModal({
      title: '  ',
      content: '           !',
     })
     }
     })
     }
    })
    index.json:データがなくて、1対の括弧だけあります。
    index.wxml
    
    <!--index.wxml-->
    <view>
     <view class="welcome">
     <view class="logo">
     <image style="width: 250rpx; height: 250rpx" src="{{logo}}"></image>
     </view>
     <view>
     <text class="words">{{welcome}}</text>
     </view>
     </view>
     
     <input class="requestURL" type="text" placeholder="{{PromoteMsg}}" focus='1' cursor='10' confirm-type="done" bindinput='getURL'></input>
     <button class='enter' bindtap='enterClicked'>{{enterBtn}}</button>
    </view>
    index.wxss
    
    /**index.wxss**/
    .welcome{
     display: flex;
     margin-top: 50rpx;
     flex-direction: column;
     align-items: center;
     justify-content: space-between;
    }
     
    .requestURL{
     margin: 50rpx 10rpx 30rpx 10rpx;
     border: 1px solid gray;
     font-style: italic;
     font-size: small
    }
     
    .enter{
     margin-right: 10rpx;
     width: 150rpx;
     height: 60rpx;
     font-size: small
    }
    4.controlディレクトリ
    control.js
    
    // pages/control/control.js
    const app = getApp()
     
    Page({
     
     /**
     *        
     */
     data: {
     // Car control images
     "forwardBtn": "/res/forward.png",
     "leftBtn": "/res/left.png",
     "rightBtn": "/res/right.png",
     "backLeftBtn": "/res/back-left.png",
     "backRightBtn": "/res/back-right.png",
     "backBtn": "/res/backward.png",
     
     // Camera control images
     "upBtn": "/res/forward.png",
     "camLeftBtn": "/res/camLeft.png",
     "camRightBtn": "/res/camRight.png",
     "downBtn": "/res/backward.png",
     "resetBtn": "/res/reset.png"
     },
     
     carMove: function(event) {
     wx.request({
     url: this.data.postURL,
     data: event.currentTarget.dataset.direction,
     method: "POST",
     success: function(res){
     
     },
     fail: function(res){
     
     }
     })
     },
     
     carStop: function(event) {
     wx.request({
     url: this.data.postURL,
     data: "S",
     method: "POST",
     success: function (res) {
     
     },
     fail: function (res) {
     
     }
     })
     },
     
     camMove: function(event) {
     wx.request({
     url: this.data.postURL,
     data: event.currentTarget.dataset.direction,
     method: "POST",
     success: function (res) {
     
     },
     fail: function (res) {
     
     }
     })
     },
     
     /**
     *       --      
     */
     onLoad: function (options) {
     //this.data.cameraURL = app.globalData.cameraURL
     this.setData({
     cameraURL: app.globalData.cameraURL,
     postURL: app.globalData.postURL
     })
     console.log(this.data.cameraURL)
     console.log("post url in control page: " + app.globalData.postURL)
     },
     
     /**
     *       --          
     */
     onReady: function () {
     
     },
     
     /**
     *       --      
     */
     onShow: function () {
     //console.log(wx.getSystemInfoSync().windowWidth)
     //console.log(wx.getSystemInfoSync().windowHeight)
     },
     
     /**
     *       --      
     */
     onHide: function () {
     
     },
     
     /**
     *       --      
     */
     onUnload: function () {
     
     },
     
     /**
     *           --        
     */
     onPullDownRefresh: function () {
     
     },
     
     /**
     *              
     */
     onReachBottom: function () {
     
     },
     
     /**
     *          
     */
     onShareAppMessage: function () {
     
     }
    })
    control.json
    
    {
     "navigationBarBackgroundColor": "#ffffff",
     "navigationBarTextStyle": "black",
     "navigationBarTitleText": "    ",
     "backgroundColor": "#eeeeee",
     "backgroundTextStyle": "light",
     "enablePullDownRefresh": false,
     "navigationStyle": "custom",
     "disableScroll": true
    }
    control.wxml
    
    <!--pages/control/control.wxml-->
    <view class='control'>
     <!-- This image shows the camera view -->
     <image class='cameraView' src='http://192.168.1.104:8080/?action=stream' style="z-index:1"></image>
     
     <!-- The following six images control the car move -->
     <image class='button' id='forward' src='{{forwardBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='F' bindtouchend='carStop'></image>
     <image class='button' id='left' src='{{leftBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='L' bindtouchend='carStop'></image>
     <image class='button' id='right' src='{{rightBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='R' bindtouchend='carStop'></image>
     <image class='button' id='backLeft' src='{{backLeftBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='BL' bindtouchend='carStop'></image>
     <image class='button' id='backRight' src='{{backRightBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='BR' bindtouchend='carStop'></image>
     <image class='button' id='back' src='{{backBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='B' bindtouchend='carStop'></image>
     
     <!-- The following images control the camera move -->
     <image class='button' id='up' src='{{upBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='VU'></image>
     <image class='button' id='camLeft' src='{{camLeftBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='HL'></image>
     <image class='button' id='camRight' src='{{camRightBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='HR'></image>
     <image class='button' id='down' src='{{downBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='VD'></image>
     <image class='button' id='reset' src='{{resetBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='RESET'></image>
    </view>
    control.wxss
    
    /* pages/control/control.wxss */
     
    .control {
     width: 100%;
     height: 100%;
     transform: rotate(90deg);
     background-color: #eee;
     justify-content: center;
    }
     
    .cameraView {
     margin-left: 0px;
     width: 603px;
     height: 375px;
     background-color: #eee;
     justify-content: center;
    }
     
    .button {
     height: 60px;
     width: 60px;
     opacity: 0.3;
    }
     
    #forward {
     left: 60px;
     top: 135px;
    }
     
    #left {
     left: 0px;
     top: 195px;
    }
     
    #right {
     left: 120px;
     top: 195px;
    }
     
    #backLeft {
     left: 0px;
     top: 255px;
    }
     
    #backRight {
     left: 120px;
     top: 255px;
    }
     
    #back {
     left: 60px;
     top: 315px;
    }
     
    #up {
     left: 480px;
     top: 195px;
    }
     
    #camLeft {
     left: 420px;
     top: 255px;
    }
     
    #camRight {
     left: 540px;
     top: 255px;
    }
     
    #down {
     left: 480px;
     top: 315px;
    }
     
    #reset{
     left: 480px;
     top: 135px
    }
    5.プロジェクト全体のコントロール
    app.js:実際には使われていないようです。中は全部工事の作成時のデフォルトコードです。
    
    //app.js
    App({
     onLaunch: function () {
     //         
     var logs = wx.getStorageSync('logs') || []
     logs.unshift(Date.now())
     wx.setStorageSync('logs', logs)
     
     //   
     wx.login({
     success: res => {
     //    res.code       openId, sessionKey, unionId
     }
     })
     //       
     wx.getSetting({
     success: res => {
     if (res.authSetting['scope.userInfo']) {
      //     ,       getUserInfo       ,    
      wx.getUserInfo({
      success: res => {
      //     res          unionId
      this.globalData.userInfo = res.userInfo
     
      //    getUserInfo      ,     Page.onLoad      
      //        callback        
      if (this.userInfoReadyCallback) {
      this.userInfoReadyCallback(res)
      }
      }
      })
     }
     }
     })
     },
     globalData: {
     userInfo: null,
     postURL: null,
     cameraURL: null
     }
    })
    app.json:
    
    {
     "pages": [
     "pages/index/index",
     "pages/control/control"
     ],
     "window": {
     "backgroundTextStyle": "light",
     "navigationBarBackgroundColor": "#fff",
     "navigationBarTitleText": "    ",
     "navigationBarTextStyle": "black",
     "showStatusBar": false
     }
    }
    app.wxss:
    
    /**app.wxss**/
    .container {
     height: 100%;
     display: flex;
     flex-direction: column;
     align-items: center;
     justify-content: space-between;
     padding: 200rpx 0;
     box-sizing: border-box;
    } 
    project.control.json:
    {
     "description": "      。",
     "packOptions": {
     "ignore": []
     },
     "setting": {
     "urlCheck": false,
     "es6": true,
     "postcss": true,
     "minified": true,
     "newFeature": true
     },
     "compileType": "miniprogram",
     "libVersion": "2.0.4",
     "appid": "wx18414b9f85bfc895",
     "projectname": "wechat-control",
     "isGameTourist": false,
     "condition": {
     "search": {
     "current": -1,
     "list": []
     },
     "conversation": {
     "current": -1,
     "list": []
     },
     "game": {
     "currentL": -1,
     "list": []
     },
     "miniprogram": {
     "current": -1,
     "list": []
     }
     }
    }
    以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。