Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

153
LINES

< > BotCompany Repo | #1027266 // Run Vector SDK v2 [can eval any Python code]

JavaX source code (Dynamic Module) [tags: use-pretranspiled] - run with: Stefan's OS

Uses 911K of libraries. Click here for Pure Java version (9366L/50K).

!7

cmodule RunVectorSDK > DynPrintLogAndEnabled {
  switchable bool printImages;
  switchable bool keepControl;
  switchable double checkTouchedInterval = 30.0; // seconds. also for checking connection liveness
  S toSay;
  
  transient Process process;
  transient PrintStream out;
  transient WithTimestamp<Bool> isBeingTouched;
  
  start-thread {
    dm_registerAs_direct vectorSDK();
    dm_reloadOnFieldChange enabled();
    dm_onFieldChange keepControl(r { if (keepControl) requestControl(); else releaseControl(); });
    
    doEvery(checkTouchedInterval, r {
      checkBeingTouched();
      restartIfNoEvents();
    });
    
    _startSDK();
  }
  
  void _startSDK q {
    cleanMeUp_process();
    if (!enabled) ret;
    //File script = userDir("vector-sdk/cam-stream-to-stdout.py");
    File script = userDir("vector-sdk/control-from-java-v2.py");
    assertFileExists(script);
    makeExecutable(script);

    print("Calling " + script);
    process = Runtime.getRuntime().exec(platformQuoteOpt(script));
    print("SDK process started");
    print("PID: " + getOpt(process, "pid"));
  
    drainErrorStreamToConsole(process, line -> enabled, lambda0 enter);
    out = new PrintStream(process.getOutputStream());
    
    isBeingTouched = WithTimestamp(null);
    
    dm_startThread("SDK Input", r {
      DataInputStream in = new(process.getInputStream());
      S line;
      while ((line = in.readLine()) != null) {
        if (enabled) {
          vmBus_send vectorSDK_gotLine(module(), line);
          if (eqic(line, "Connected to vector")) {
            vmBus_send vectorSDK_connected(module());
            if (keepControl)
              requestControl();
            checkBeingTouched();
          }
          if (printImages || !startsWith(line, "img:"))
            print("Got line: " + takeFirst(100, line));
          if (eq(line, "Unknown error"))
            _startSDK();
          if (startsWith(line, "touch:"))
            isBeingTouched = WithTimestamp(match("true", afterColon(line)));
        }
      }
    });
  }

  void cleanMeUp_process {
    if (process != null) {
      print("Stopping SDK process");
      process.destroy/*Forcibly*/();
      process = null;
      print("Stopped SDK process, hopefully");
    }
  }
  
  visual centerAndSouthWithMargin(super,
    westAndCenterWithMargins(
      dm_checkBox keepControl(),
      dm_textFieldAndSubmit_q toSay(r { say(toSay) }, buttonText := "Say")));

  // API
  
  void eval(S pythonCode) {
    if (out == null || empty(pythonCode)) ret;
    out.println(jsonEncode(pythonCode));
    out.flush();
  }
  
  void evalWithControl(S pythonCode) {
    if (keepControl)
      ret with eval(pythonCode);
    print("evalWithControl: " + pythonCode);
    eval("with anki_vector.Robot() as robot2:\n" +
      indent(4, jreplace(pythonCode, "robot", "robot2")));
  }

  // returns true if (probably) successful
  bool say(S s) {
    if (out == null) false;
    s = newLinesToSpaces_trim(s);
    if (empty(s)) true;
    print("Making Vector say: " + s);
    // with release_control, there is "unknown error" after first utterance
    /*eval(autoUnindent(linesLL(
      "robot.conn.request_control(timeout=5.0)",
      "robot.behavior.say_text(" + pythonQuote(s) + ")",
      //"robot.conn.release_control()"
    )));*/
    /*eval("with anki_vector.Robot() as robot2:\n" +
      "    robot2.behavior.say_text(" + pythonQuote(s) + ")");*/
    evalWithControl("robot.behavior.say_text(" + pythonQuote(s) + ")");
    true;
  }
  
  void playWAV(File wav) {
    print("Playing: " + wav);
    if (!is16KMonoWAVFile(wav)) {
      print("Converting to 16k");
      File wav2 = javaxCachesDir("vector.wav");
      deleteFile(wav2);
      ffmpeg_toMonoAudio_16k(wav, wav2);
      if (!fileExists(wav2)) fail("Conversion failed");
      wav = wav2;
    }
    int volume = 75;
    evalWithControl("robot.audio.stream_wav_file(" + pythonQuote(f2s(wav)) + ", " + volume + ")";
  }
  
  void startCamStream {
    eval("camFeedOn()");
  }
  
  void checkBeingTouched() {
    eval([[print("touch: " + str(robot.touch.last_sensor_reading.is_being_touched))]]);
  }
  
  // request control in main connection. currently not sure how to undo
  void requestControl() {
    eval("robot.conn.request_control()");
  }
  
  // Not working in tests?
  void releaseControl() {
    eval("robot.conn.release_control()");
  }
  
  void restartIfNoEvents() {
    if (isBeingTouched != null && isBeingTouched.olderThanSeconds(checkTouchedInterval*2.0)) {
      isBeingTouched = WithTimestamp(null);
      _startSDK();
    }
  }
}

Author comment

Began life as a copy of #1027258

download  show line numbers  debug dex  old transpilations   

Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1027266
Snippet name: Run Vector SDK v2 [can eval any Python code]
Eternal ID of this version: #1027266/43
Text MD5: 4bc95525898a7535ee94c0bbcd6190ad
Transpilation MD5: 8365e6508c1fadffebbe8fd305633a08
Author: stefan
Category: javax / anki vector
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-04-05 02:01:55
Source code size: 4731 bytes / 153 lines
Pitched / IR pitched: No / No
Views / Downloads: 315 / 5604
Version history: 42 change(s)
Referenced in: [show references]