From d1f2103d6f9378010e23b33f05990f5ba3e711d7 Mon Sep 17 00:00:00 2001
From: Robert Hedman <robert.hedman@mac.com>
Date: Sun, 26 Nov 2017 23:16:37 +0100
Subject: [PATCH] Functioning emulated lidar and serial communication threads
 in one program.

---
 Cargo.lock  |  61 ++++++++++++++++++++
 Cargo.toml  |   1 +
 src/main.rs | 160 ++++++++++++++++++++++++++++++++--------------------
 3 files changed, 161 insertions(+), 61 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 0b7acd1..cde1a0a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -103,6 +103,14 @@ dependencies = [
  "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "ioctl-rs"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "jpeg-decoder"
 version = "0.1.13"
@@ -211,6 +219,7 @@ name = "rorientation"
 version = "0.1.0"
 dependencies = [
  "image 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -223,6 +232,52 @@ name = "scopeguard"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "serial"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serial-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serial-unix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serial-windows 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serial-core"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serial-unix"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ioctl-rs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serial-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serial-windows"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serial-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "termios"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [metadata]
 "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
@@ -238,6 +293,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum gif 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e41945ba23db3bf51b24756d73d81acb4f28d85c3dccc32c6fae904438c25f"
 "checksum image 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1576ffa01849c91b484b95c01d54dddc242b4d50923eaa2d4d74a58c4b9e8fd"
 "checksum inflate 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10ec05638adf7c5c788bc0cfa608cd479a13572beda20feb4898fe1d85d2c64b"
+"checksum ioctl-rs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f7970510895cee30b3e9128319f2cefd4bde883a39f38baa279567ba3a7eb97d"
 "checksum jpeg-decoder 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2805ccb10ffe4d10e06ef68a158ff94c255211ecbae848fbde2146b098f93ce7"
 "checksum lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "236eb37a62591d4a41a89b7763d7de3e06ca02d5ab2815446a8bae5d2f8c2d57"
 "checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2"
@@ -253,3 +309,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53"
 "checksum scoped_threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4ea459fe3ceff01e09534847c49860891d3ff1c12b4eb7731b67f2778fb60190"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
+"checksum serial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a1237a96570fc377c13baa1b88c7589ab66edced652e43ffb17088f003db3e86"
+"checksum serial-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f46209b345401737ae2125fe5b19a77acce90cd53e1658cda928e4fe9a64581"
+"checksum serial-unix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f03fbca4c9d866e24a459cbca71283f545a37f8e3e002ad8c70593871453cab7"
+"checksum serial-windows 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15c6d3b776267a75d31bbdfd5d36c0ca051251caafc285827052bc53bcdc8162"
+"checksum termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a"
diff --git a/Cargo.toml b/Cargo.toml
index c8e2825..4dd9285 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,3 +5,4 @@ authors = ["Robert Hedman <robert.hedman@mac.com>"]
 
 [dependencies]
 image = "*"
+serial = "0.4"
diff --git a/src/main.rs b/src/main.rs
index 44a5cce..845340a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,6 +7,13 @@ use std::io::prelude::*;
 use std::net::TcpStream;
 use std::net::TcpListener;
 
+// stuff for serial
+extern crate serial;
+use std::io;
+use std::time::Duration;
+use std::io::prelude::*;
+use serial::prelude::*;
+
 use std::str;
 
 // should the map matrix be two dim array of const size, vecs of dynamic, or what?
@@ -16,6 +23,30 @@ const ROWS: usize = 50;
 const COLS: usize = 100;
 
 fn main() {
+    // dummy thread for replacing lidar
+    let server = thread::spawn(|| {
+        let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
+        let mut stream;
+        let mut message =  [0u8; 2];
+        match listener.accept() {
+            Ok((socket, addr)) => {
+                println!("server: new client: {:?}", addr); stream=socket;
+                thread::sleep(time::Duration::new(1,0));
+                loop {
+                    match stream.read_exact(&mut message) {
+                        Ok(msg) => {println!("server got: {} {}", message[0], message[1]);
+                        let written_size = stream.write(&[69 as u8, 96 as u8]);
+                        println!("server wrote {:?} to stream.", written_size);
+                        },
+                        Err(e) => {println!("Some error in readToString in swerver: {}", e)},
+                    }
+                }
+            },
+            Err(e) => println!("couldn't get client: {:?}", e),
+        }
+    });
+
+
     let mut map = [[0u32; ROWS]; COLS];
     map[0][0] = 3;
 
@@ -27,18 +58,32 @@ fn main() {
     // location tracker
     let tracker = thread::spawn(move || {
         println!("Tracker started.");
+        
+        let mut serialBuf: [u8; 8] = [0; 8];
+        let device = String::from("/dev/cu.usbmodem41");
+        let mut port = serial::open(&device).unwrap();
+        interact(&mut port).unwrap();
+
+        let mut L: i32 = 0;
+        let mut R: i32 = 0;
+        
         let mut pos: (i32, i32) = (0,0);
         loop {
-            // get encoder data from arduino
-            let mut t: i32 = 0;
-            for _ in 0..1000 {
-                t = t+1;
-            };
-            for _ in 0..1000 {
-                t = t-1;
-            };
+            // get encoder data from arduino and update local variables
+            match port.read_exact(&mut serialBuf){
+                Ok(_) => {
+                    L = freq_to_distance( ( ((serialBuf[0] as u32) << 24) + ((serialBuf[1] as u32) << 16) + ((serialBuf[2] as u32) << 8) + (serialBuf[3] as u32) ) as i32);
+                    R = freq_to_distance( ( ((serialBuf[4] as u32) << 24) + ((serialBuf[5] as u32) << 16) + ((serialBuf[6] as u32) << 8) + (serialBuf[7] as u32) ) as i32);
+                    print!("L: {}, ", L);
+                    println!("R: {}", R);
+                    pos.0 += L;
+                    pos.1 += R;
+                    },
+                Err(e) => {
+                    println!("Could not read all bytes: {:?}", e);
+                },
+            }
 
-            // update local variables
 
             // check if position is requested
             match request_location_rx.try_recv() {
@@ -60,11 +105,20 @@ fn main() {
         println!("tracker exiting with local pos: {:?}", pos);
    
     });
+
+
+
     // mapper (gets lidar data, requests position and updates its map.)
     let mapper = thread::spawn(move || {
         println!("mapper started.");
         // create empty map
         let mut pos: (i32, i32); //= (0,0);
+
+        // set up connection to lidar
+        let mut stream = TcpStream::connect("127.0.0.1:8080").unwrap();
+        let mut lidarBuf: [u8; 2] = [0; 2];
+
+        // main loop for this thread
         loop {
             // request position data
             request_location_tx.send(true).unwrap();
@@ -75,15 +129,28 @@ fn main() {
             
 
             // request lidar data
+            thread::sleep(time::Duration::new(3,0));     
+            let stream_write_response = stream.write(&[65 as u8, 66 as u8]);
+            println!("mapper wrote {:?} to stream.", stream_write_response);
+
+            match stream.read_exact(&mut lidarBuf){
+                Ok(_) => {
+                    println!("mapper got {}, {}, from lidar.", lidarBuf[0], lidarBuf[1]);
+                    },
+                Err(e) => {
+                    println!("Could not read all bytes: {:?}", e);
+                },
+            }
 
             // update map
 
+
             if pos.0 == 2000 {
                 println!("mapper done.");
                 request_location_tx.send(false).unwrap();
                 break;
             }
-            //thread::sleep(time::Duration::new(0,50*1000000)); // from ms to ns
+            thread::sleep(time::Duration::new(1,0*50*1000000)); // from ms to ns
         };
 
         
@@ -91,57 +158,6 @@ fn main() {
     });
 
 
-    let server = thread::spawn(|| {
-        let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
-        let mut stream;
-        let mut message =  [0u8; 128];
-        match listener.accept() {
-            Ok((socket, addr)) => {
-                println!("server: new client: {:?}", addr); stream=socket;
-                thread::sleep(time::Duration::new(1,0));
-                loop {
-                    match stream.read(&mut message) {
-                        Ok(msg) => {println!("server got: {:?}, local message: {}", msg, str::from_utf8(&message).unwrap());
-                        let written_size = stream.write_all("Server says hi.\n".as_bytes());
-                        println!("server wrote_all {:?} to stream.", written_size);
-                        },
-                        Err(e) => {println!("Some error in readToString in swerver: {}", e)},
-                    }
-                }
-            },
-            Err(e) => println!("couldn't get client: {:?}", e),
-        }
-    });
-
-    thread::sleep(time::Duration::new(3,0));
-    let mut stream = TcpStream::connect("127.0.0.1:8080").unwrap();
-    //thread::sleep(time::Duration::new(0,900*1000000));
-    //let written_size = stream.write(&['y' as u8,'o' as u8, '!' as u8]);
-    //println!("main wrote {:?} bytes to stream.", written_size);
-
-    let written_size = stream.write_all("Main says hi.".as_bytes());
-    println!("main wrote_all {:?} to stream.", written_size);
-
-    let mut stream_copy = stream.try_clone().unwrap();
-    let mut c: u8 = 0;
-    for b in stream.bytes() {
-        match b {
-            Ok(byte) => {print!("{}", byte as char);
-            if c == 14 {
-                c = 0;
-                let _ = stream_copy.write_all("Hi Server, Me Main, got your message!".as_bytes());
-            }
-            else {
-                c += 1;
-            }
-            
-            },
-            Err(_) => {},
-        }
-    }
-    
-
-
     println!("Main wating for join.");
     mapper.join().unwrap();
     tracker.join().unwrap();
@@ -155,4 +171,26 @@ fn main() {
 
     //
 
+}
+
+
+
+
+fn interact<T: SerialPort>(port: &mut T) -> io::Result<()> {
+    try!(port.reconfigure(&|settings| {
+        try!(settings.set_baud_rate(serial::Baud9600));
+        settings.set_char_size(serial::Bits8);
+        settings.set_parity(serial::ParityNone);
+        settings.set_stop_bits(serial::Stop1);
+        settings.set_flow_control(serial::FlowNone);
+        Ok(())
+    }));
+ try!(port.set_timeout(Duration::from_millis(10000)));
+
+    Ok(())
+}
+
+
+fn freq_to_distance(freq: i32) -> i32 {
+    freq/10
 }
\ No newline at end of file
-- 
GitLab