Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

F109 us905 ta2104 bt to wifi lidar #47

Merged
merged 27 commits into from
Dec 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
427a239
streaming over wifi at all times
calin-pescaru Nov 24, 2022
0eae09d
the app is notified when lidar detects an object
calin-pescaru Nov 25, 2022
c0b2ead
sound is played when object detected by LiDAR
calin-pescaru Nov 27, 2022
182307f
play different sounds when an object is at different distances
calin-pescaru Nov 27, 2022
d37bb2c
added medium distance and text label for distance in the main view
calin-pescaru Nov 27, 2022
f06fa8c
reverted to one distance on the Pi; send all distances over BT
calin-pescaru Nov 28, 2022
c648004
some changes for alerts and user configuration
calin-pescaru Dec 2, 2022
c4795cd
option to detect vehicles only
calin-pescaru Dec 2, 2022
fd8527b
xcode stuff
calin-pescaru Dec 2, 2022
cae16d1
Merge branch 'main' into F109-US905-TA2104-bt-to-wifi
calin-pescaru Dec 2, 2022
8c28294
Refactor test to test directory for consistency.
jon-dez Nov 23, 2022
a947322
Various modifications:
jon-dez Nov 23, 2022
d83b5eb
Work around for an edge case when connecting...
jon-dez Nov 23, 2022
2f5eb85
Refactor:
jon-dez Nov 23, 2022
06ef4e9
Modifications to the accelerometer code.
jon-dez Nov 24, 2022
f262879
Instructions to disable unused bluetooth plugins.
jon-dez Nov 28, 2022
7d06ceb
Update to device configuration via bluetooth.
jon-dez Dec 2, 2022
04bff2e
lidar config changes
jon-dez Dec 2, 2022
7b87e0a
update
jon-dez Dec 2, 2022
45f5eb5
fixed merge conflicts
calin-pescaru Dec 3, 2022
f148910
fixed conflicts
calin-pescaru Dec 3, 2022
dfe09aa
small changes
calin-pescaru Dec 3, 2022
f1b9497
Update rear_rider_device/rear_rider_bluetooth_server/src/services/hel…
calin-pescaru Dec 3, 2022
a6870a8
Update rear_rider_device/rear_rider_bluetooth_server/src/services/hel…
calin-pescaru Dec 3, 2022
d4525e4
Update rear_rider_device/main.py
calin-pescaru Dec 3, 2022
072b0a6
fixed crashing bug
calin-pescaru Dec 3, 2022
601bef3
added app icon
calin-pescaru Dec 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,25 @@ Now the Bluetooth server starts when the Pi boots. Also, Bluetooth has to be in

The application has three tabs. The first tab is the main view. Here the rider can see alerts when an object is approaching (TBD). The next view is the Live Streaming. The app will connect to the Pi over Wi-Fi and stream a live feed from the camera. The user has the option to record the streaming and to use ML to detect the objects in the feed. The last tab is the settings tab (TBD). At the top of the screen there are two icons that show if the Bluetooth and Wi-Fi connections are available by turning green.

## Disabling Unnecessary Bluetooth Services

By default Raspbian's bluetooth service includes AVRCP, which is for the capability of streaming audio to the raspberry pi, but we do not require this. Also, the bluetooth service includes SAP (Sim Access Profile) which we do not make use of. Do the following to disable those features:

```bash
sudo systemctl edit bluetooth.service
```

Then, add the following lines to the indicated regions.

```conf
[Service]
# First clear the responsible variable.
ExecStart=
# Then reassign it with the aforemention plugins disabled.
ExecStart=/usr/libexec/bluetooth/bluetoothd --noplugin=sap,avrcp
```


## Contributing

### Updating requirements.txt
Expand Down
12 changes: 8 additions & 4 deletions Rear Rider/Rear Rider.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
C36AA2E728FC80B2001F24A3 /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36AA2E428FC80B2001F24A3 /* ShareSheet.swift */; };
C36AA2E828FC80B2001F24A3 /* RecordingExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36AA2E528FC80B2001F24A3 /* RecordingExtension.swift */; };
C36AA2EC28FC8278001F24A3 /* RiderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36AA2EB28FC8278001F24A3 /* RiderView.swift */; };
C39C7C2D2933C2AD007A5884 /* beep.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C39C7C2C2933C2AD007A5884 /* beep.mp3 */; };
C3A64EB329172F2A0067FDF0 /* BLETests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A64EB229172F2A0067FDF0 /* BLETests.swift */; };
C3BD658328E8DB3B0042CEB4 /* BLEManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3BD658228E8DB3B0042CEB4 /* BLEManager.swift */; };
C3FC5C66290C64B800929D1D /* yolov5m.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = C3FC5C65290C64B800929D1D /* yolov5m.mlmodel */; };
Expand Down Expand Up @@ -98,6 +99,7 @@
C36AA2E428FC80B2001F24A3 /* ShareSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareSheet.swift; sourceTree = "<group>"; };
C36AA2E528FC80B2001F24A3 /* RecordingExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecordingExtension.swift; sourceTree = "<group>"; };
C36AA2EB28FC8278001F24A3 /* RiderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RiderView.swift; sourceTree = "<group>"; };
C39C7C2C2933C2AD007A5884 /* beep.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = beep.mp3; sourceTree = "<group>"; };
C3A64EB229172F2A0067FDF0 /* BLETests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BLETests.swift; sourceTree = "<group>"; };
C3BD658228E8DB3B0042CEB4 /* BLEManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BLEManager.swift; sourceTree = "<group>"; };
C3FC5C65290C64B800929D1D /* yolov5m.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = yolov5m.mlmodel; sourceTree = "<group>"; };
Expand Down Expand Up @@ -182,6 +184,7 @@
4845584329089489002D81FC /* Alerts */ = {
isa = PBXGroup;
children = (
C39C7C2C2933C2AD007A5884 /* beep.mp3 */,
48CB852E2902EF5200283DBD /* vehicleAlert.mp3 */,
48CB852C2902E60700283DBD /* RearRiderAlerts.swift */,
);
Expand Down Expand Up @@ -380,6 +383,7 @@
buildActionMask = 2147483647;
files = (
4851CE1028E49485003B5B76 /* Preview Assets.xcassets in Resources */,
C39C7C2D2933C2AD007A5884 /* beep.mp3 in Resources */,
483E42B4291BE71800B9A3C3 /* GoogleService-Info.plist in Resources */,
4851CE0D28E49485003B5B76 /* Assets.xcassets in Resources */,
48CB852F2902EF5200283DBD /* vehicleAlert.mp3 in Resources */,
Expand Down Expand Up @@ -574,7 +578,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Rear Rider/Preview Content\"";
DEVELOPMENT_TEAM = 5KVT845VZL;
DEVELOPMENT_TEAM = T53AYVVL5N;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "This app requires Bluetooth for connecting to RaspberryPi";
Expand All @@ -588,7 +592,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = RearRider;
PRODUCT_BUNDLE_IDENTIFIER = com.Calin.RearRider;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
Expand All @@ -604,7 +608,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Rear Rider/Preview Content\"";
DEVELOPMENT_TEAM = 5KVT845VZL;
DEVELOPMENT_TEAM = T53AYVVL5N;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "This app requires Bluetooth for connecting to RaspberryPi";
Expand All @@ -618,7 +622,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = RearRider;
PRODUCT_BUNDLE_IDENTIFIER = com.Calin.RearRider;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
Expand Down
Binary file not shown.
53 changes: 37 additions & 16 deletions Rear Rider/Rear Rider/Alerts/RearRiderAlerts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,37 @@ enum AlertErrors: Error {
case fileNotFound(String)
}


/**
* Class for managing any audio and visual alerts for the rider
*/
class RearRiderAlerts: ObservableObject {
var mLModel = ImageIdentification()
var mLModel = ImageIdentification.shared
var player: AVAudioPlayer!
var soundFile: URL! = nil

var unsafe_distance: Int = 900
@Published var distance: Int = 0
var alert_enabled: Bool = true
var vehicles_only: Bool = true

@Published var frame: UIImage = UIImage()
static var shared = RearRiderAlerts()

var picData = NSMutableData()
var pic_size:Int = 0
var pic_first_time:Bool = true

init() {
do {
try AVAudioSession.sharedInstance().setCategory(
AVAudioSession.Category.multiRoute, // this setting allows the sound to be played on the speaker instead of Bluetooth
options: AVAudioSession.CategoryOptions.duckOthers)

try AVAudioSession.sharedInstance().setActive(true)
} catch let error {
print(error)
}
}

/// When this is set, the transfer of the packets will commence
var pic_packets:Int = 0 {
Expand All @@ -46,7 +61,7 @@ class RearRiderAlerts: ObservableObject {
mLModel.detectObjects(image: frame)
pic_first_time = true
picData = NSMutableData()
if mLModel.detected_objs.isEmpty { askForPic() } // if no objects detect ask for another pic
if mLModel.bndRects.isEmpty { askForPic() } // if no objects detect ask for another pic
}
else {
BLEManager.shared.getPicPacket(index: packet_recv)
Expand Down Expand Up @@ -79,24 +94,30 @@ class RearRiderAlerts: ObservableObject {
func playAudioAlert() {
// do nothing if we don't have a sound file configured
if soundFile == nil { return }

do {
try AVAudioSession.sharedInstance().setCategory(
AVAudioSession.Category.playback,
options: AVAudioSession.CategoryOptions.duckOthers
)

try AVAudioSession.sharedInstance().setActive(true)
player.play()
} catch let error {
print(error)
}
player.play()
}

/// Asks the RPi for the picture's metadata (size and number of packets)
func askForPic() {
mLModel.detected_objs.removeAll()
//mLModel.detected_objs.removeAll()
mLModel.clearBndRects()
BLEManager.shared.getPicInfo()
}

/// Play an alert sound when necessary
/// - Parameter d: Distance of the object detected by LiDAR
func alert_rider(distance d: Int) {
self.distance = d

if d <= unsafe_distance && alert_enabled {
if vehicles_only {
if mLModel.checkForVehicles() {
playAudioAlert()
}
}
else {
playAudioAlert()
}
}
}
}
Binary file added Rear Rider/Rear Rider/Alerts/beep.mp3
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"size" : "60x60"
},
{
"filename" : "rearrider_180x180.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions Rear Rider/Rear Rider/BlueTooth/BLEManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct CBUUIDs {
static let BLEConfigCharacteristicUUID = CBUUID(string: "501beabd-3f66-4cca-ba7a-0fbf4f81870c")
static let BLEWifiCharacteristicUUID = CBUUID(string: "cd41b278-6254-4c89-9cd1-fd2578ab8fcc")
static let BLEPictureCharacteristicUUID = CBUUID(string: "cd41b278-6254-4c89-9cd1-fd2578ab8abb")
static let BLELiDARCharacteristicUUID = CBUUID(string: "92cb916f-d996-4f30-8cba-cf3ab8aede56")
}

/// The purpose of this class is to set the iPhone as a central manager and connect to the RaspberryPi as a peripheral
Expand All @@ -36,6 +37,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
private var configCharacteristic: CBCharacteristic!
private var wifiCharacteristic: CBCharacteristic!
private var picCharacteristic: CBCharacteristic!
private var lidarCharacteristic: CBCharacteristic!

//mostly for testing purposes
var ConfigCharacteristic: CBCharacteristic {
Expand Down Expand Up @@ -217,6 +219,12 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
log.addLog(from: "BT", message: "Picture Characteristic set")
connected = true
}
else if characteristic.uuid.isEqual(CBUUIDs.BLELiDARCharacteristicUUID) {
lidarCharacteristic = characteristic
log.addLog(from: "BT", message: "LiDAR Characteristic set")
peripheral.setNotifyValue(true, for: lidarCharacteristic)
connected = true
}
}
}

Expand Down Expand Up @@ -267,6 +275,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
}
}
}
else if characteristic == lidarCharacteristic {
let d = String(data: characteristic.value ?? Data(), encoding: String.Encoding.utf8)
if d != nil {
let distance: Int = Int(d ?? "0") ?? 0
RearRiderAlerts.shared.alert_rider(distance: distance)
}
}
}

/// Called when the state of the connection changes
Expand All @@ -276,6 +291,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
func peripheral(_ peripheral: CBPeripheral, didModifyServices invalidatedServices: [CBService]) {
connected = false
log.addLog(from: "BT", message: "RPi disconnected")
startScanning() // try to reconnect
}

/// Called when the peripheral disconnects
Expand All @@ -289,6 +305,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
print("RPi disconnected")
log.addLog(from: "BT", message: "RPi disconnected")
connected = false
startScanning() // try to reconnect
}
}

Expand Down
41 changes: 39 additions & 2 deletions Rear Rider/Rear Rider/ConfigurationOptions/OptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,19 @@ struct OptionsView: View {
@State var confLightPattern: Int = 1
@State var confLightBrightness: Int = 1
@State var confLightColor: Color = .white
@State var confAlertToggle: Bool = true
@State var confVehiclesOnly: Bool = true
@State var confUnsafeDistance: Float = 17.0 // this index represents 900 in the array below

var distance_text = ["50", "100", "150", "200", "250", "300",
"350", "400", "450", "500", "550", "600",
"650", "700", "750", "800", "850", "900", "950", "1000"]

let audioFiles: [ConfigOptions.AudioFile] = ConfigOptions.AudioFile.allCases
let lightPatterns: [ConfigOptions.LightPattern] = ConfigOptions.LightPattern.allCases
let lightBrightness: [ConfigOptions.LightBrightness] = ConfigOptions.LightBrightness.allCases

let alert = RearRiderAlerts()
let alert = RearRiderAlerts.shared

var body: some View {
VStack {
Expand All @@ -45,8 +52,14 @@ struct OptionsView: View {
audioFile in Text(audioFile.description).tag(audioFile.rawValue)
}
})
Toggle("Sound", isOn: $confAlertToggle.onChange(setAlert))
Toggle("Vehicles Only", isOn: $confVehiclesOnly.onChange(setVehiclesOnly))
HStack {
Slider(value: $confUnsafeDistance.onChange(setDistance), in: 0...19, step: 1)
Text("Distance: \(distance_text[Int(confUnsafeDistance)]) cm")
}
} header: {
Text("Audio")
Text("LiDAR")
}
Section {
Picker("Pattern", selection: $confLightPattern.onChange(setLights), content: {
Expand Down Expand Up @@ -83,6 +96,9 @@ struct OptionsView: View {
confLightBrightness = conf.lightBrightness
confLightPattern = conf.lightPattern
confLightColor = Color.fromRGBString(rgbString: conf.lightColor)
confAlertToggle = conf.alertToggle
confVehiclesOnly = conf.vehiclesOnly
confUnsafeDistance = Float(distance_text.lastIndex(of: String(conf.unsafeDistance)) ?? 0)
}
}

Expand All @@ -100,6 +116,27 @@ struct OptionsView: View {
}
}

/// Enable alerts
/// - Parameter value: true to enable
func setAlert(to value: Bool) {
conf.alertToggle = confAlertToggle
saveConf()
}

/// Set the unsafe distance
/// - Parameter value: the index of distance_text array
func setDistance(to value: Float) {
conf.unsafeDistance = Int(distance_text[Int(confUnsafeDistance)]) ?? 0
saveConf()
}

/// Alerts will be played only if the object detected is a vehicle
/// - Parameter value: true or false
func setVehiclesOnly(to value: Bool) {
conf.vehiclesOnly = confVehiclesOnly
saveConf()
}

/**
* Sets the config object's light pattern to the new selection and saves it
*/
Expand Down
Loading