isl-org / OpenBot

OpenBot leverages smartphones as brains for low-cost robots. We have designed a small electric vehicle that costs about $50 and serves as a robot body. Our software stack for Android smartphones supports advanced robotics workloads such as person following and real-time autonomous navigation.
https://www.openbot.org
MIT License
2.82k stars 528 forks source link

App crashes in Autopilot fragment, when "Auto Mode" switch is activated #209

Closed MohammedZ666 closed 3 years ago

MohammedZ666 commented 3 years ago

Bug Description App crashes in the Autopilot fragment when the Auto Mode switch is activated.

To Reproduce Steps to reproduce the behavior:

  1. Go to Autopilot
  2. Turn on the Auto Mode switch
  3. App may immediately crash
  4. Logcat:
    07-22 10:07:53.736 27209-27581/org.openbot E/AndroidRuntime: FATAL EXCEPTION: inference
    Process: org.openbot, PID: 27209
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
        at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8203)
        at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1309)
        at android.view.ViewGroup.invalidateChild(ViewGroup.java:5430)
        at android.view.View.invalidateInternal(View.java:13959)
        at android.view.View.invalidate(View.java:13923)
        at android.view.View.invalidate(View.java:13907)
        at android.widget.TextView.checkForRelayout(TextView.java:8373)
        at android.widget.TextView.setText(TextView.java:5001)
        at android.widget.TextView.setText(TextView.java:4828)
        at android.widget.TextView.setText(TextView.java:4803)
        at org.openbot.autopilot.AutopilotFragment.handleDriveCommand(AutopilotFragment.java:443)
        at org.openbot.autopilot.AutopilotFragment.lambda$processFrame$18$AutopilotFragment(AutopilotFragment.java:424)
        at org.openbot.autopilot.-$$Lambda$AutopilotFragment$AD5NQvceNuqdJYNKu4y74kjwNKo.run(lambda)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.os.HandlerThread.run(HandlerThread.java:61)

Fix In AutopilotFragment.handleDriveCommand the textview controlInfo is being updated from a child thread. It should be called from the main thread, in this way:

  protected void handleDriveCommand(Control control) {
    vehicle.setControl(control);
    float left = vehicle.getLeftSpeed();
    float right = vehicle.getRightSpeed();
    requireActivity()
        .runOnUiThread(
            () ->
                binding.controllerContainer.controlInfo.setText(
                    String.format(Locale.US, "%.0f,%.0f", left, right)));
  }

In the same way, the onConnectionEstablished is updating another text view:

@Override
  public void onConnectionEstablished(String ipAddress) {
    requireActivity().runOnUiThread(() -> binding.ipAddress.setText(ipAddress));
  }

Screenshots Here is the gif for better explanation: ezgif com-gif-maker

Smartphone (please complete the following information):

Additional context Add any other context about the problem here.

thias15 commented 3 years ago

Interesting. In newer versions of Android this is not a problem.

thias15 commented 3 years ago

Fixed in #210