seattlers / coding_workshop_toy_car

Toy Car Coding Workshop
Apache License 2.0
1 stars 0 forks source link

workshop scope - control methodology #4

Open U007D opened 5 years ago

U007D commented 5 years ago

interactive control (wireless, via bluetooth from phone?) autonomous (using on-board sensor, choose random direction)

Driver is whether we can find/build a bluetooth remote control solution on the phone. As this is not a part of this particular workshop, any tech is fine, as long as it is reliable and usable by both Android and iPhone users.

modulitos commented 5 years ago

It seems like a bluetooth wireless controller can be implemented as a phone app in React native. Here are some tutorial links:

Using RN: https://medium.com/@daniel.lima.nascimento/how-to-create-a-bluetooth-app-with-react-native-5212d8590e6b Using RN with Expo: https://blog.expo.io/so-you-want-to-build-a-bluetooth-app-with-react-native-and-expo-6ea6a31a151d

And here are a couple libraries that provide a BLE (Bluetooth Low Energy) module in RN: https://www.npmjs.com/package/react-native-ble-manager https://www.npmjs.com/package/react-native-ble-plx


UPDATE (2019.04.23)

There are also some webapp options worth exploring. Here are some resources:

https://github.com/WebBluetoothCG/demos https://developers.google.com/web/updates/2015/07/interact-with-ble-devices-on-the-web https://googlechrome.github.io/samples/web-bluetooth/index.html

I've never used RN nor built a native app, but I'm willing to spend a day or so to spike a proof of concept. That might give us an idea on how deep this :rabbit: :hole: goes.

And of course, I'm always open to feedback :+1:

oceanlewis commented 5 years ago

I'd definitely be free to review anything you come up with if you think that would be helpful :). My experience with React Native is pretty minimal, but I'll help how I can!

Our alternatives if crossplatform BLE doesn't pan out would be obstacle detection with a sonic sensor. Either way, getting to the point where we're thinking about how to steer our car is a big win, and would still be months down the road.

modulitos commented 5 years ago

I spent a day on this, and I got blocked on a few issues in both iOS and Android development. My general takeaway is that without some native-app expertise, this will take a lot more time than I had anticipated 😬

So here are some options that I see moving forward:


I tried following the Expo guide linked in my comment above. I documented some details of my attempt below, in case anyone is interested in exploring or providing feedback.

I created a repo here: https://github.com/modulitos/toycarcontroller where I followed the step-by-step instructions.

iOS

I made it to the last step, where I needed to run: Product > Build in XCode. But then I was blocked with an error:

:0: error: module map file '/Users/lucas/Library/Developer/Xcode/DerivedData/toy-car-controller-dugchbqfnckptbdvzvmsgritjdtz/Build/Products/Debug-iphonesimulator/react-native-ble-plx-swift/react_native_ble_plx_swift.modulemap' not found :0: error: module map file '/Users/lucas/Library/Developer/Xcode/DerivedData/toy-car-controller-dugchbqfnckptbdvzvmsgritjdtz/Build/Products/Debug-iphonesimulator/react-native-ble-plx-swift/react_native_ble_plx_swift.modulemap' not found 2 errors generated. :0: error: failed to emit precompiled header '/Users/lucas/Library/Developer/Xcode/DerivedData/toy-car-controller-dugchbqfnckptbdvzvmsgritjdtz/Build/Intermediates.noindex/PrecompiledHeaders/toy-car-controller-Bridging-Header-swift_2WLMXVBMTOLWI-clang_1G208F3Z8FHLX.pch' for bridging header '/Users/lucas/projects/toy-car/controller/ios/toy-car-controller-Bridging-Header.h'

There seems to be an issue with linking the React Native bluetooth module here: https://github.com/modulitos/toycarcontroller/commit/a9e38a77b94cac534d906deb40302a30979e3d53

My intuition here is pretty limited, since this is my first time doing mobile development.

Android

I made it to the last step on the Android app, and the app successfully built after connecting my Android phone and running the command react-native run-android:

Installed on 1 device.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0. Use '--warning-mode all' to show the individual deprecation warnings. See https://docs.gradle.org/5.1.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 3s 41 actionable tasks: 2 executed, 39 up-to-date Running adb -s 8BKX1BH2P reverse tcp:8081 tcp:8081 Starting the app on 8BKX1BH2P (adb -s 8BKX1BH2P shell am start -n host.exp.exponent/host.exp.exponent.MainActivity)... Starting: Intent { cmp=host.exp.exponent/.MainActivity } Error type 3 Error: Activity class {host.exp.exponent/host.exp.exponent.MainActivity} does not exist.

But it looks like there was still an error in getting the app to run. I suspect this isn't caused by the build, and might be fixed by building out the app logic.

U007D commented 5 years ago

Yowza! Ok, thanks for this, @modulitos. It seems that a simple sensing robot would be a good first step, with an eye on making it remote controllable only if/when a solution presents itself. I'll be at OxidizeConf, and will ask around while I'm there if anyone has any ideas.

Assuming nothing ready-made drops itself in our laps, that would mean the project would be simpler: 1) reading from whatever sensor we choose, 2) making a decision based on that input and 3) driving the motors appropriately.

There's nothing stopping us from adding remote controllability to the project as a separate step later on if there is interest. WDYT?

modulitos commented 5 years ago

@U007D Yes, that sounds like a great path forward 😁

I think starting on the Rust modules will give us some time, and motivation, to figure out the sensory input.

If we're lucky, the Expo team will ship Bluetooth support by the time we are ready to make that decision 🤞

modulitos commented 5 years ago

Note: this was originally posted in our chat

UPDATE Instead of as web bluetooth controller, we can assume the laptop as the "remote control", and punt the bluetooth control until a later date, after we make more progress on the car.


Below is a proof of concept to demonstrate how a static website using Web Bluetooth can connect with a BLE device.

Here are steps to repro the proof of concept:

Download the "BLE peripheral simulator" app on Google Play (sorry, I didn't explore an iphone option): https://github.com/WebBluetoothCG/ble-test-peripheral-android

This app allows us to test the Web Bluetooth without needing a BLE Peripheral Device. Note that our car will eventually be the BLE device that is simulated by the app ;)

Once the app is downloaded, open the app on your phone.

Then on a separate machine, visit this website using Google Chrome:

https://webbluetoothcg.github.io/demos/heart-rate-sensor/

Click the "Get ❤" button in the center of the web page. A pop up will appear, scanning for BLE devices, and your phone should appear. Click on your phone to pair with it.

Within the phone app, click "Heart Rate Monitor", change the "Heart Rate" number to any number you'd like (eg: 42), and click "notify".

The web page should display the number 42 🎉


As for next steps, I think a reasonable MVP is to control an LED that is mounted to our RISC board over Web Bluetooth.

There is a repo of web bluetooth demos here: https://github.com/WebBluetoothCG/demos

I'm going to explore this demo, which is for a controlling LED's over web bluetooth: https://github.com/WebBluetoothCG/demos/tree/gh-pages/bluetooth-led-display

I'll also need to read up on GATT, which is the protocol used by Web Bluetooth: https://www.bluetooth.com/specifications/gatt/

Unfortunately, it may not be trivial to implement the GATT protocol for a BLE device: https://www.oreilly.com/library/view/getting-started-with/9781491900550/ch04.html#gatt_hrs_img

Or we can try reverse-engineering the Android API to see how it's implemented. Here is the Android lib for a BLE GATT implementation: https://developer.android.com/reference/android/bluetooth/BluetoothGattService.html and here is where it is being used in the BLE Simulator codebase: https://github.com/WebBluetoothCG/ble-test-peripheral-android/blob/master/app/src/main/java/io/github/webbluetoothcg/bletestperipheral/HeartRateServiceFragment.java

I'll also need to start reading up on the Rust embedded discovery book, because I have no idea how to implement BLE devices on a RISC board.