diff --git a/# backup/01 debug_panto_heartbeats.py b/# backup/01 debug_panto_heartbeats.py
deleted file mode 100644
index a4ab0d1..0000000
--- a/# backup/01 debug_panto_heartbeats.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import serial
-import binascii
-
-com = "/dev/cu.usbserial-0001"
-
-con = serial.Serial(com, baudrate=115200, timeout=5)
-while True:
- header = con.read(size=2)
- print(binascii.hexlify(header))
-
- msg_type = con.read(size=1)
- print(binascii.hexlify(msg_type))
-
- package_id = con.read(size=1)
- print(binascii.hexlify(package_id))
-
- message_size = con.read(size=2)
- print(binascii.hexlify(message_size))
-
- body = con.read(size=int.from_bytes(message_size, byteorder="big"))
- print(binascii.hexlify(body))
-
- if msg_type == bytes.fromhex("20"):
- print("received debug message:")
- print(body)
-
-con.close()
\ No newline at end of file
diff --git a/# backup/02 debug_panto.py b/# backup/02 debug_panto.py
deleted file mode 100644
index 06b4c52..0000000
--- a/# backup/02 debug_panto.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import serial
-import binascii
-import logging
-
-com = "/dev/cu.usbserial-0001"
-
-logging.basicConfig(level=logging.INFO)
-
-con = serial.Serial(com, baudrate=115200, timeout=5)
-
-while True:
- header = con.read(size=2)
-
- msg_type = con.read(size=1)
-
- package_id = con.read(size=1)
-
-
- message_size = con.read(size=2)
-
-
- body = con.read(size=int.from_bytes(message_size, byteorder="big"))
-
-
- if msg_type == bytes.fromhex("20"):
- logging.info("received debug message:")
- logging.info(body)
-
- elif msg_type == bytes.fromhex("00"):
- logging.info("receive sync")
- con.write(bytes.fromhex("445080000000"))
- elif msg_type == bytes.fromhex("01"):
- logging.info("receive heartbeat")
- con.write(bytes.fromhex("445081000000"))
- elif msg_type == bytes.fromhex("10"):
- logging.info("receive position")
- """
- 4450 // magic number
- 10 // message type: position
- 00 // packet ID: not utilized
- 0028 // payload length: 2 handles, 5 values each, 4 bytes each - 2*5*4 = 40 = 0x28
- FFFFFFFF // x position of first handle
- FFFFFFFF // y position of first handle
- FFFFFFFF // rotation of first handle
- FFFFFFFF // x position of first handle's god object
- FFFFFFFF // y position of first handle's god object
- FFFFFFFF // x position of second handle
- FFFFFFFF // y position of second handle
- FFFFFFFF // rotation of second handle
- FFFFFFFF // x position of second handle's god object
- FFFFFFFF // y position of second handle's god object
- """
- x_1 = int.from_bytes(body[:4], byteorder='big', signed=False)
- y_1 = int.from_bytes(body[4:8], byteorder='big', signed=False)
- r_1 = int.from_bytes(body[8:12], byteorder='big', signed=False)
- g_x1 = int.from_bytes(body[12:16], byteorder='big', signed=False)
- g_y1 = int.from_bytes(body[16:20], byteorder='big', signed=False)
- x_2 = int.from_bytes(body[20:24], byteorder='big', signed=False)
- y_2 = int.from_bytes(body[24:28], byteorder='big', signed=False)
- r_2 = int.from_bytes(body[28:32], byteorder='big', signed=False)
- g_x2 = int.from_bytes(body[32:36], byteorder='big', signed=False)
- g_y2 = int.from_bytes(body[36:40], byteorder='big', signed=False)
-
-
- logging.info(f"{x_1} {y_1} {r_1} {g_x1} {g_y1} {x_2} {y_2} {r_2} {g_x2} {g_y2}")
- else:
- logging.warning(binascii.hexlify(header))
-
- logging.warning((binascii.hexlify(msg_type)))
-
- logging.warning(binascii.hexlify(package_id))
- logging.warning(binascii.hexlify(message_size))
- logging.warning(binascii.hexlify(body))
-
-con.close()
\ No newline at end of file
diff --git a/# backup/todo.md b/# backup/todo.md
deleted file mode 100644
index c44f66f..0000000
--- a/# backup/todo.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# UX
-- download pycharm
- - platformio is hard to use
-
-- finding comport
- - mac: all time same , /dev/cu.SLAB_USBtoUART
- - windows: a user need to chekc COM number on device manager
- - Linux: "/dev/ttyUSB0" maybe
- - first of all, they need to install the driver
-
-- encoder test
-
- - we don't know which number is which
- - we don't know when we can say it works properly
- - a user move linkage to the end and check the value is correct or not
- - we need some documentation or video
-
-- add mecnanical linkage test
-
-- motor (sync) test
- -
-
-
diff --git a/.gitmodules b/.gitmodules
index caf0633..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "firmware/10 panto firmware"]
- path = firmware/10 panto firmware
- url = git@github.com:HassoPlattnerInstituteHCI/dualpantoframework.git
diff --git a/BIS/BIS.md b/BIS/BIS.md
new file mode 100644
index 0000000..27233f1
--- /dev/null
+++ b/BIS/BIS.md
@@ -0,0 +1,29 @@
+# BIS
+
+We use this dualpanto-testing repo for assignment, and uploading dualpanto firmware too.
+
+**Please check and install all requirements at [Readme.md](../Readme.md)**
+
+
+## Assignment Week7: rendering wall
+Assignment for Week7 is to write code of god objeect partially, and get familiar with uploading firmware and this testing work flow.
+
+1. make sure install ESP32 driver, IDE, and all python library on requirements.txt
+2. go to `dualpant-testing/firmware/haptics/BIS week7/src`,find TODO and write code
+3. `python -m unittest test_firmware.Haptics.test_BIS_week7`
+4. if you feel the device has issue, follow [test flow (Mechanics and Hardware)](../Readme.md)
+5. take the video that you interacts with rendered wall
+
+## Assignment Week8:
+**WIP**
+
+## Uploading DualpantoFramework
+From Week9, we will develop dualpanto app. sometimes you want to upload dualpanto famework again and again when...
+
+1. you update dualpanto framework (e.g. you tune PID)
+2. you plug dualpanto device into different PC
+ - we observe dualpanto has some wall rendering issue when you connect dualpanto to other PC. e.g, you uplaod firmware from mac and connect to windows pc.
+ - this is not always happend. but You need to keep this in mind.
+ - We haven't known why so. Welcome you to contribute here!
+
+`python -m unittest test_firmware.UploadDualpantoFrameowrk.test_upload_dp_firmware`
diff --git a/BIS/before_ask_ta.md b/BIS/before_ask_ta.md
new file mode 100644
index 0000000..e69de29
diff --git a/CheckLists/mechanical.md b/CheckLists/mechanical.md
deleted file mode 100644
index ea9b1f7..0000000
--- a/CheckLists/mechanical.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Checking Mechanical and some random Issue
-First things you needs to check is mechanical issue
-(or assembly issue) of dualpanto device.
-
-#### #01 Home the linkages by moving them to the initial position and reset the microcontroller
-#### #02 Reconnect the USB cable (power cycling)
-#### #03 Check your battery level
-#### #04 check motor solder connection
-#### #05 check connection between motor and linkages: one set screw should be against the “d-cut” of the shaft
\ No newline at end of file
diff --git a/Readme.md b/Readme.md
index cc9d4c5..957d0c2 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,6 +1,11 @@
# Dualpanto Testing
-Goal of this repository is to provide some (semi) automatic testing for the dualpanto platform. This involves basic functionality checks of the hardware, the firmware and potentially the unity integration
+The goal of this repository is to provide (semi) automatic testing for the dualpanto platform. This involves basic functionality checks of the hardware, the haptic rendering and the unity integration.
+
+This project is work-in-progress. Welcome you to contribute.
+### For BIS participants
+Please check [BIS.md](BIS/BIS.md) first.
+
## Requirements
### Install the ESP32 driver
@@ -18,8 +23,6 @@ We highly recommend to use PyCharm to run this test flow.
you can run unittest from Markdown preview (or [execute unittest from scripts](https://www.jetbrains.com/help/pycharm/testing-your-first-python-application.html#create-test))
-[//]: # ()
-
#### VScode
@@ -32,22 +35,18 @@ you can run unittest from Markdown preview (or [execute unittest from scripts](
you can also run all unittest from command line interface if you want.
# Test Flow
-If you don't have any intuition about where the issue that you have comes from,
-you want to test from bottom up: mechanical -> hardware -> framework -> communication ->unity.
-
-Some of the test is not software automatable since they are related to haptics and mechanics. check `How to test?`.
+Most of the test is not semi-automated since they are related to haptics and mechanical issue. Check `How to test?`.
## Configurate test flow
-1. open `config.py` and enter your ESP port.
-2. when you upload a firmware, you need to push button back of dualpanto. please check [this](https://github.com/HassoPlattnerInstituteHCI/dualpanto/blob/main/BIS.md#upload-firmware)
-.
+1. open `config.py` and enter your ESP port.
+2. when you upload a firmware, you probably need to push button back of dualpanto (it depends on OS).
+
## 1. Mechanical and Hardware
-test with IDE or from command line
-0. [check mechanical configuration](CheckLists/mechanical.md)
+0. [check mechanical configuration](physical_test%2Fmechanical_issue_check_list.md)
1. `python -m unittest test_firmware.Basic`
2. `python -m unittest test_hardware.Linkage.test_encoder`[How to test?]()
3. `python -m unittest test_hardware.Linkage.test_sync`[How to test?]()
@@ -62,7 +61,8 @@ flowchart TD;
subgraph test_firmware
FB[1.Basic];
- FB -- not work --> TA0((Ask TA))
+ FB -- not work --> CH(check USB connection,
COM port and
platformIO properly installed)
+ CH -- no idea --> TA0((Ask TA))
end
FB -- work --> LTE[2.test_Encoder]
@@ -93,12 +93,9 @@ flowchart TD;
click MC "https://discord.com"
```
-## 2. Firmware
-**WIP**
-
-test with IDE or from command line
+## 2. Rendering Haptics = DualPanto Firmware
-0. [check mechanical configuration](CheckLists/mechanical.md)
+0. [check mechanical configuration](physical_test/mechanical.md)
1. `python -m unittest test_firmware.Haptics.test_line_wall` [How to test?]()
2. `python -m unittest test_firmware.Haptics.test_force_field` **WIP**
3. `python -m unittest test_firmware.Haptics.test_rail` **WIP**
@@ -107,65 +104,16 @@ test with IDE or from command line
6. `python -m unittest test_firmware.Haptics.test_moving_obstacle` **WIP**
7. `python -m unittest test_firmware.Kinematics.test_forward` **WIP**
8. `python -m unittest test_firmware.Kinematics.test_inverse` **WIP**
+9. (WIP: mathing it and me's rocation for each dualpanto)
-```mermaid
-%%{init: {'theme': 'neutral' } }%%
-flowchart TD;
- ST((start)) --> MC[mechanical];
- MC -- checked --> TLW;
-
- subgraph test_firmware.Haptics
- TLW[1.test_line_wall] --> TFF[2.test_force_field]
- TLW --not work--> TA0((Ask TA))
- TFF --> TR[3.test_rail]
- TR --> DONE((done))
-
-%% TR[test_rail]
-%%
-%% TRW[test_rectangle_obstacle]
-%%
-%% TMW[test_moving_obstacle]
-
-
- end
-
-
-
- style TA0 fill:#FF9B00
- style DONE fill:#99CC00
-
-```
## 3. Communication between DualPanto and PC
**WIP**
-test with IDE or from command line
-
-1. `python -m unittest test_hardware.HardwareTest.test_compile_firmware` [How to test?]()
-
-```mermaid
-%%{init: {'theme': 'neutral' } }%%
-flowchart TD;
- ST((start)) --> MC[mechanical];
-
- subgraph test_protocol
- MC[test_message_count]-- work -->SGO[test_set_god_object];
- end
-```
-
-Please clone the current panto firmware into `firmware/10 panto firmware` and run `npm run script config`
-
-On a firmware level we need to test that the dualpanto can
-- perform the handshake
-- keep the connection alive
-- move the handles if instructed
-- report the handle position
-- accept obstacles
-- render obstacles
-
## 4. Unity (Communication between DualPanto and Unity)
-TODO
+
+**WIP**
## Development
This project is currenty under developement.
diff --git a/firmware/10 panto firmware b/firmware/10 panto firmware
deleted file mode 160000
index d1fe262..0000000
--- a/firmware/10 panto firmware
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit d1fe262166f9b4056af7a65c5f623c22d5555f52
diff --git a/firmware/09 god object/firmware/.gitignore b/firmware/haptics/BIS week7/firmware/.gitignore
similarity index 100%
rename from firmware/09 god object/firmware/.gitignore
rename to firmware/haptics/BIS week7/firmware/.gitignore
diff --git a/firmware/09 god object/firmware/.idea/.gitignore b/firmware/haptics/BIS week7/firmware/.idea/.gitignore
similarity index 100%
rename from firmware/09 god object/firmware/.idea/.gitignore
rename to firmware/haptics/BIS week7/firmware/.idea/.gitignore
diff --git a/firmware/09 god object/firmware/.idea/misc.xml b/firmware/haptics/BIS week7/firmware/.idea/misc.xml
similarity index 100%
rename from firmware/09 god object/firmware/.idea/misc.xml
rename to firmware/haptics/BIS week7/firmware/.idea/misc.xml
diff --git a/firmware/09 god object/firmware/.idea/vcs.xml b/firmware/haptics/BIS week7/firmware/.idea/vcs.xml
similarity index 100%
rename from firmware/09 god object/firmware/.idea/vcs.xml
rename to firmware/haptics/BIS week7/firmware/.idea/vcs.xml
diff --git a/firmware/09 god object/firmware/include/config/config.hpp b/firmware/haptics/BIS week7/firmware/include/config/config.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/config/config.hpp
rename to firmware/haptics/BIS week7/firmware/include/config/config.hpp
diff --git a/firmware/09 god object/firmware/include/hardware/angleAccessor.hpp b/firmware/haptics/BIS week7/firmware/include/hardware/angleAccessor.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/hardware/angleAccessor.hpp
rename to firmware/haptics/BIS week7/firmware/include/hardware/angleAccessor.hpp
diff --git a/firmware/09 god object/firmware/include/hardware/panto.hpp b/firmware/haptics/BIS week7/firmware/include/hardware/panto.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/hardware/panto.hpp
rename to firmware/haptics/BIS week7/firmware/include/hardware/panto.hpp
diff --git a/firmware/09 god object/firmware/include/hardware/spiCommands.hpp b/firmware/haptics/BIS week7/firmware/include/hardware/spiCommands.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/hardware/spiCommands.hpp
rename to firmware/haptics/BIS week7/firmware/include/hardware/spiCommands.hpp
diff --git a/firmware/09 god object/firmware/include/hardware/spiEncoder.hpp b/firmware/haptics/BIS week7/firmware/include/hardware/spiEncoder.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/hardware/spiEncoder.hpp
rename to firmware/haptics/BIS week7/firmware/include/hardware/spiEncoder.hpp
diff --git a/firmware/09 god object/firmware/include/hardware/spiEncoderChain.hpp b/firmware/haptics/BIS week7/firmware/include/hardware/spiEncoderChain.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/hardware/spiEncoderChain.hpp
rename to firmware/haptics/BIS week7/firmware/include/hardware/spiEncoderChain.hpp
diff --git a/firmware/09 god object/firmware/include/hardware/spiPacket.hpp b/firmware/haptics/BIS week7/firmware/include/hardware/spiPacket.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/hardware/spiPacket.hpp
rename to firmware/haptics/BIS week7/firmware/include/hardware/spiPacket.hpp
diff --git a/firmware/09 god object/firmware/include/ioMain.hpp b/firmware/haptics/BIS week7/firmware/include/ioMain.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/ioMain.hpp
rename to firmware/haptics/BIS week7/firmware/include/ioMain.hpp
diff --git a/firmware/09 god object/firmware/include/physics/annotatedEdge.hpp b/firmware/haptics/BIS week7/firmware/include/physics/annotatedEdge.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/annotatedEdge.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/annotatedEdge.hpp
diff --git a/firmware/09 god object/firmware/include/physics/collider.hpp b/firmware/haptics/BIS week7/firmware/include/physics/collider.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/collider.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/collider.hpp
diff --git a/firmware/09 god object/firmware/include/physics/edge.hpp b/firmware/haptics/BIS week7/firmware/include/physics/edge.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/edge.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/edge.hpp
diff --git a/firmware/09 god object/firmware/include/physics/godObject.hpp b/firmware/haptics/BIS week7/firmware/include/physics/godObject.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/godObject.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/godObject.hpp
diff --git a/firmware/09 god object/firmware/include/physics/godObjectAction.hpp b/firmware/haptics/BIS week7/firmware/include/physics/godObjectAction.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/godObjectAction.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/godObjectAction.hpp
diff --git a/firmware/09 god object/firmware/include/physics/godObjectActionData.hpp b/firmware/haptics/BIS week7/firmware/include/physics/godObjectActionData.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/godObjectActionData.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/godObjectActionData.hpp
diff --git a/firmware/09 god object/firmware/include/physics/godObjectActionType.hpp b/firmware/haptics/BIS week7/firmware/include/physics/godObjectActionType.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/godObjectActionType.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/godObjectActionType.hpp
diff --git a/firmware/09 god object/firmware/include/physics/hashtable.hpp b/firmware/haptics/BIS week7/firmware/include/physics/hashtable.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/hashtable.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/hashtable.hpp
diff --git a/firmware/09 god object/firmware/include/physics/indexedEdge.hpp b/firmware/haptics/BIS week7/firmware/include/physics/indexedEdge.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/indexedEdge.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/indexedEdge.hpp
diff --git a/firmware/09 god object/firmware/include/physics/obstacle.hpp b/firmware/haptics/BIS week7/firmware/include/physics/obstacle.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/obstacle.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/obstacle.hpp
diff --git a/firmware/09 god object/firmware/include/physics/pantoPhysics.hpp b/firmware/haptics/BIS week7/firmware/include/physics/pantoPhysics.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/pantoPhysics.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/pantoPhysics.hpp
diff --git a/firmware/09 god object/firmware/include/physics/rail.hpp b/firmware/haptics/BIS week7/firmware/include/physics/rail.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physics/rail.hpp
rename to firmware/haptics/BIS week7/firmware/include/physics/rail.hpp
diff --git a/firmware/09 god object/firmware/include/physicsMain.hpp b/firmware/haptics/BIS week7/firmware/include/physicsMain.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/physicsMain.hpp
rename to firmware/haptics/BIS week7/firmware/include/physicsMain.hpp
diff --git a/firmware/09 god object/firmware/include/tasks/task.hpp b/firmware/haptics/BIS week7/firmware/include/tasks/task.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/tasks/task.hpp
rename to firmware/haptics/BIS week7/firmware/include/tasks/task.hpp
diff --git a/firmware/09 god object/firmware/include/tasks/taskFunction.hpp b/firmware/haptics/BIS week7/firmware/include/tasks/taskFunction.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/tasks/taskFunction.hpp
rename to firmware/haptics/BIS week7/firmware/include/tasks/taskFunction.hpp
diff --git a/firmware/09 god object/firmware/include/tasks/taskRegistry.hpp b/firmware/haptics/BIS week7/firmware/include/tasks/taskRegistry.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/tasks/taskRegistry.hpp
rename to firmware/haptics/BIS week7/firmware/include/tasks/taskRegistry.hpp
diff --git a/firmware/09 god object/firmware/include/utils/assert.hpp b/firmware/haptics/BIS week7/firmware/include/utils/assert.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/utils/assert.hpp
rename to firmware/haptics/BIS week7/firmware/include/utils/assert.hpp
diff --git a/firmware/09 god object/firmware/include/utils/crashDump.hpp b/firmware/haptics/BIS week7/firmware/include/utils/crashDump.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/utils/crashDump.hpp
rename to firmware/haptics/BIS week7/firmware/include/utils/crashDump.hpp
diff --git a/firmware/09 god object/firmware/include/utils/framerateLimiter.hpp b/firmware/haptics/BIS week7/firmware/include/utils/framerateLimiter.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/utils/framerateLimiter.hpp
rename to firmware/haptics/BIS week7/firmware/include/utils/framerateLimiter.hpp
diff --git a/firmware/09 god object/firmware/include/utils/performanceMonitor.hpp b/firmware/haptics/BIS week7/firmware/include/utils/performanceMonitor.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/utils/performanceMonitor.hpp
rename to firmware/haptics/BIS week7/firmware/include/utils/performanceMonitor.hpp
diff --git a/firmware/09 god object/firmware/include/utils/receiveHandler.hpp b/firmware/haptics/BIS week7/firmware/include/utils/receiveHandler.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/utils/receiveHandler.hpp
rename to firmware/haptics/BIS week7/firmware/include/utils/receiveHandler.hpp
diff --git a/firmware/09 god object/firmware/include/utils/receiveState.hpp b/firmware/haptics/BIS week7/firmware/include/utils/receiveState.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/utils/receiveState.hpp
rename to firmware/haptics/BIS week7/firmware/include/utils/receiveState.hpp
diff --git a/firmware/09 god object/firmware/include/utils/serial.hpp b/firmware/haptics/BIS week7/firmware/include/utils/serial.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/utils/serial.hpp
rename to firmware/haptics/BIS week7/firmware/include/utils/serial.hpp
diff --git a/firmware/09 god object/firmware/include/utils/utils.hpp b/firmware/haptics/BIS week7/firmware/include/utils/utils.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/utils/utils.hpp
rename to firmware/haptics/BIS week7/firmware/include/utils/utils.hpp
diff --git a/firmware/09 god object/firmware/include/utils/vector.hpp b/firmware/haptics/BIS week7/firmware/include/utils/vector.hpp
similarity index 100%
rename from firmware/09 god object/firmware/include/utils/vector.hpp
rename to firmware/haptics/BIS week7/firmware/include/utils/vector.hpp
diff --git a/firmware/09 god object/firmware/platformio.ini b/firmware/haptics/BIS week7/firmware/platformio.ini
similarity index 100%
rename from firmware/09 god object/firmware/platformio.ini
rename to firmware/haptics/BIS week7/firmware/platformio.ini
diff --git a/firmware/09 god object/firmware/src/config/config.cpp b/firmware/haptics/BIS week7/firmware/src/config/config.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/config/config.cpp
rename to firmware/haptics/BIS week7/firmware/src/config/config.cpp
diff --git a/firmware/09 god object/firmware/src/hardware/panto.cpp b/firmware/haptics/BIS week7/firmware/src/hardware/panto.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/hardware/panto.cpp
rename to firmware/haptics/BIS week7/firmware/src/hardware/panto.cpp
diff --git a/firmware/09 god object/firmware/src/hardware/spiCommands.cpp b/firmware/haptics/BIS week7/firmware/src/hardware/spiCommands.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/hardware/spiCommands.cpp
rename to firmware/haptics/BIS week7/firmware/src/hardware/spiCommands.cpp
diff --git a/firmware/09 god object/firmware/src/hardware/spiEncoder.cpp b/firmware/haptics/BIS week7/firmware/src/hardware/spiEncoder.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/hardware/spiEncoder.cpp
rename to firmware/haptics/BIS week7/firmware/src/hardware/spiEncoder.cpp
diff --git a/firmware/09 god object/firmware/src/hardware/spiEncoderChain.cpp b/firmware/haptics/BIS week7/firmware/src/hardware/spiEncoderChain.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/hardware/spiEncoderChain.cpp
rename to firmware/haptics/BIS week7/firmware/src/hardware/spiEncoderChain.cpp
diff --git a/firmware/09 god object/firmware/src/hardware/spiPacket.cpp b/firmware/haptics/BIS week7/firmware/src/hardware/spiPacket.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/hardware/spiPacket.cpp
rename to firmware/haptics/BIS week7/firmware/src/hardware/spiPacket.cpp
diff --git a/firmware/09 god object/firmware/src/ioMain.cpp b/firmware/haptics/BIS week7/firmware/src/ioMain.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/ioMain.cpp
rename to firmware/haptics/BIS week7/firmware/src/ioMain.cpp
diff --git a/firmware/09 god object/firmware/src/main.cpp b/firmware/haptics/BIS week7/firmware/src/main.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/main.cpp
rename to firmware/haptics/BIS week7/firmware/src/main.cpp
diff --git a/firmware/09 god object/firmware/src/physics/annotatedEdge.cpp b/firmware/haptics/BIS week7/firmware/src/physics/annotatedEdge.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/physics/annotatedEdge.cpp
rename to firmware/haptics/BIS week7/firmware/src/physics/annotatedEdge.cpp
diff --git a/firmware/09 god object/firmware/src/physics/collider.cpp b/firmware/haptics/BIS week7/firmware/src/physics/collider.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/physics/collider.cpp
rename to firmware/haptics/BIS week7/firmware/src/physics/collider.cpp
diff --git a/firmware/haptics/BIS week7/firmware/src/physics/godObject.cpp b/firmware/haptics/BIS week7/firmware/src/physics/godObject.cpp
new file mode 100644
index 0000000..9d62211
--- /dev/null
+++ b/firmware/haptics/BIS week7/firmware/src/physics/godObject.cpp
@@ -0,0 +1,486 @@
+#include "physics/godObject.hpp"
+
+#include "config/config.hpp"
+#include "utils/serial.hpp"
+
+GodObject::GodObject(Vector2D position)
+ : m_position(position), m_tetherPosition(position), m_obstacleMutex(portMUX_INITIALIZER_UNLOCKED), m_possibleCollisions(new std::set())
+{
+}
+
+GodObject::~GodObject()
+{
+ delete m_possibleCollisions;
+}
+
+void GodObject::setMovementDirection(Vector2D movementDirection)
+{
+ m_movementDirection = movementDirection;
+}
+
+Hashtable& GodObject::hashtable()
+{
+ if (!m_hashtable)
+ {
+ m_hashtable = new Hashtable();
+ }
+ return *m_hashtable;
+}
+
+void GodObject::update()
+{
+ if (m_actionQueue.empty())
+ {
+ return;
+ }
+
+ portENTER_CRITICAL(&m_obstacleMutex);
+ for (auto i = 0; i < obstacleChangesPerFrame && !m_actionQueue.empty(); ++i)
+ {
+ auto action = m_actionQueue.front();
+ m_actionQueue.pop_front();
+ switch (action->m_type)
+ {
+ case HT_ENABLE_EDGE:
+ {
+ hashtable().add(action->m_data.m_annotatedEdge);
+ break;
+ }
+ case HT_DISABLE_EDGE:
+ {
+ hashtable().remove(action->m_data.m_annotatedEdge);
+ break;
+ }
+ case GO_REMOVE_OBSTACLE:
+ {
+ try{
+
+ delete m_obstacles.at(action->m_data.m_obstacleId);
+ m_obstacles.erase(action->m_data.m_obstacleId);
+ } catch (const std::out_of_range &oor){
+ DPSerial::sendInstantDebugLog("Could not remove obstacle");
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ delete action;
+ }
+ portEXIT_CRITICAL(&m_obstacleMutex);
+}
+
+void GodObject::dumpHashtable()
+{
+ portENTER_CRITICAL(&m_obstacleMutex);
+ hashtable().print();
+ portEXIT_CRITICAL(&m_obstacleMutex);
+}
+
+// returns if force is applied or not
+bool GodObject::move(bool isTweening, bool isFrozen)
+{
+ auto lastState = m_processingObstacleCollision;
+ // if the number of collisions increased since the last frame then we ran into a corner
+ auto lastNumCollisions = m_numCollisions;
+
+ m_processingObstacleCollision = false;
+
+
+ Vector2D nextGoPosition;
+ Vector2D handlePosition = m_position + m_movementDirection;
+ if (isFrozen){
+ renderForce(getCollisionForce(m_position, handlePosition), Vector2D(0,0));
+ return true;
+ }
+ if (isTweening) {
+ m_position = handlePosition;
+ if (m_tethered) {
+ m_tetherPosition = handlePosition;
+ }
+ return false;
+ }
+ float movementStepLength = m_movementDirection.length(); // only used for tethering
+ if (m_tethered && !isTweening) {
+ double distHandleToGo = m_movementDirection.length();
+ if ((distHandleToGo < m_tetherInnerRadius) || (m_tetherState!=Outer && (distHandleToGo > 10))) {
+ // the latter condition can happen at startup of the device.
+ // in this case we don't want to apply forces.
+ m_tetherState = Inner;
+ return false;
+ }
+ // find out the current tether state
+ if (distHandleToGo > m_tetherInnerRadius && distHandleToGo < m_tetherOuterRadius){
+ m_tetherState = Active;
+ } else {
+ m_tetherState = Outer;
+ }
+ // the speed of the god object increases proportionally with the distance bw handle and go. The max speed of the go is dependent on the outer tether radius.
+ movementStepLength = min(m_tetherOuterRadius, distHandleToGo);
+
+ // this is the movement of the god object that follows the tether
+ if (distHandleToGo != 0)
+ {
+ nextGoPosition = m_position + (m_movementDirection.normalize() * movementStepLength * m_tetherFactor);
+ } else {
+ nextGoPosition = handlePosition;
+ }
+ } else {
+ nextGoPosition = handlePosition;
+ }
+
+ // no matter what the tether state is we need to check if the god object is colliding with an obstacle
+ Vector2D godObjectPos;
+ portENTER_CRITICAL(&m_obstacleMutex);
+ if (m_tethered && m_tetherState == Outer && m_tetherStrategy == Exploration){
+ // pausing the game means that the god object position doesn't update.
+ godObjectPos = m_position;
+ } else {
+ // this is the default case
+ godObjectPos = checkCollisions(nextGoPosition, m_position);
+ }
+ if (m_tethered && m_processingObstacleCollision && m_tetherState == Outer && m_tetherStrategy != MaxSpeed) {
+ // for the Exploration and Leash mode the tether state can't be outer once the god object collides
+ // (otherwise the wall force will be weaker when the handle moves further into the wall)
+ m_tetherState = Active;
+ }
+
+ // check if collision with a passable obstacle or a haptic guide is present
+ if (m_tethered && m_processingObstacleCollision && m_tetherState == Active) {
+ m_processingObstacleCollision = false;
+ nextGoPosition = m_position + (m_movementDirection.normalize() * movementStepLength * c_railsTetherFactor);
+ auto pos = checkCollisions(nextGoPosition, m_position);
+ // if the handle is already past the obstacle (no more collision present) then the god object jumps to its position
+ if (!m_processingObstacleCollision) {
+ m_position = pos;
+ } else {
+ m_position = godObjectPos;
+ }
+ } else {
+ m_position = godObjectPos;
+ }
+
+ if (m_tethered && m_tetherState == Outer && !isTweening && m_tetherStrategy != MaxSpeed)
+ {
+ m_tetherPosition = checkCollisions(handlePosition, m_tetherPosition);
+ } else {
+ m_tetherPosition = handlePosition;
+ }
+ portEXIT_CRITICAL(&m_obstacleMutex);
+
+ m_doneColliding = lastState && !m_processingObstacleCollision;
+
+ if (!m_tethered) {
+ if (m_processingObstacleCollision)
+ {
+ renderForce(getCollisionForce(m_position, handlePosition), Vector2D(0,0));
+ }
+ return m_processingObstacleCollision;
+ } else {
+ // newCollision is only important for the pock
+ bool newCollision = lastNumCollisions < m_numCollisions;
+ return processTetheringForce(handlePosition, newCollision);
+ }
+}
+
+Vector2D GodObject::getCollisionForce(Vector2D godObjectPosition, Vector2D handlePosition){
+
+ // TODO:
+ // Given a position of god-object and the position of the handle,
+ // calculate rendering force.
+
+ // Variables given:
+ // Vector2D godObjectPosition, handlePosition : position of god-object and handle.
+ // float K : proportional gain for force used in the god-object rendering.
+
+ // Returns:
+ // Vector2D force, rendering force that you will apply to the device.
+
+ const float K = forcePidFactor[0][0]; // check config.hpp for PID parameter
+ Vector2D force = Vector2D(0,0);
+
+ // YOUR CODE STARTS
+
+
+ // YOUR CODE ENDS
+ return force;
+}
+
+Vector2D GodObject::getTetherForce(Vector2D error){
+ auto force = 0
+ return force;
+}
+
+void GodObject::renderForce(Vector2D collisionForce, Vector2D tetherForce) {
+ m_activeForce = collisionForce + tetherForce;
+}
+
+bool GodObject::processTetheringForce(Vector2D handlePosition, bool newCollision) {
+ // returns if force is active or handle is freely moving
+ if (m_tetherState==Outer && m_tetherStrategy!=MaxSpeed) {
+ // for the 2 tether strategies where the god object is pulled on a virtual leash towards the tether position
+ auto error = m_movementDirection.normalize() * c_tetherForcePullingBack;
+ auto tetherForce = getTetherForce(error); //TODO: if we had a collision previously in Active state and moved from there into Outer state then the rendered force should be the sum of the previous force and the collision force
+ if (m_processingObstacleCollision) {
+ // think about adding a second pock here as well
+ renderForce(getCollisionForce(m_tetherPosition, handlePosition), tetherForce);
+ } else {
+ // weak constant force pulling the tether back to the god object
+ renderForce(Vector2D(0,0), tetherForce);
+ }
+ return true;
+ } else {
+ auto movementLength = (m_tetherPosition - m_position).length();
+ auto error = m_movementDirection.normalize() * (m_tetherInnerRadius - movementLength);
+ if (newCollision && m_tetherPockEnabled) {
+ // weak constant force pushing the handle into the the wall so that the user gets force feedback at their fingertip
+ error = m_movementDirection.normalize() * c_tetherPockDistance; // this can't work because we include the last tether error
+ }
+ auto tetherForce = getTetherForce(error);
+
+ if (m_processingObstacleCollision) {
+ // god object collision
+ renderForce(getCollisionForce(m_position, handlePosition), tetherForce);
+ return true;
+ } else {
+ if (!m_doneColliding) {
+ // regular tether force active that pushes the handle back to the inner tether radius
+
+ renderForce(Vector2D(0,0), tetherForce);
+ }
+ return !m_doneColliding;
+ }
+ }
+ return false;
+}
+
+Vector2D GodObject::checkCollisions(Vector2D targetPoint, Vector2D currentPosition)
+{
+ /*
+ Collision detection works in 3 stages:
+ 1. Select collision candidates using a 2D lookup table. Every cell in that table contains the edges that go through it. That's why only particular edges have to be checked for collisions.
+ 2. The actual collision detection.
+ 3. If a collision is detected calculate the new god object position.
+
+ If a collision is detected the collision detection is repeated with the new target position. This way we can check if the new position is accessible at all or not.
+
+ Added by Julius on 30.09.20
+ For more information check Lukas Wagners MT (section 4.3.1): https://www.dropbox.com/home/2018%20CHI%20Dueling%20Pantographs/Layer%202%20Firmware%20(Lukas%20Wagner)?preview=2019_09_07+ESP+Firmware+for+God+Haptic+Objects+%3D+Masterarbeit+(Lukas+Wagner).pdf
+ */
+
+ if (currentPosition == targetPoint || !m_hashtable)
+ {
+ return targetPoint;
+ }
+ // 1. select collision candidates
+ m_possibleCollisions->clear();
+ hashtable().getPossibleCollisions(
+ Edge(currentPosition, targetPoint), m_possibleCollisions);
+ if (m_possibleCollisions->empty())
+ {
+ return targetPoint;
+ }
+
+ bool foundCollision;
+ u_short numCollisions = 0;
+ // 2. check if collisions are present between 2 vectors
+ // first vector goes from god object to handle and the
+ // second vector is the potential collision edge
+ do
+ {
+ // result vars
+ foundCollision = false;
+ double shortestMovementRatio = 0;
+ Vector2D closestEdgeFirst;
+ Vector2D closestEdgeFirstMinusSecond;
+
+ // direction of movement: value is constant for loop
+ const auto posMinusTarget = currentPosition - targetPoint;
+
+ if (posMinusTarget == Vector2D(0, 0))
+ {
+ return targetPoint;
+ }
+
+ for (auto&& indexedEdge : *m_possibleCollisions)
+ {
+ auto edge = indexedEdge.m_obstacle->getEdge(indexedEdge.m_index);
+ auto edgeFirst = edge.m_first;
+ auto firstMinusPos = edgeFirst - currentPosition;
+ auto firstMinusSecond = edgeFirst - edge.m_second;
+ auto divisor =
+ Vector2D::determinant(firstMinusSecond, posMinusTarget);
+
+ auto movementRatio =
+ -Vector2D::determinant(firstMinusSecond, firstMinusPos) /
+ divisor;
+ if (movementRatio < 0 || movementRatio > 1)
+ {
+ continue;
+ }
+
+ auto edgeRatio =
+ Vector2D::determinant(firstMinusPos, posMinusTarget) / divisor;
+ if (edgeRatio < 0 || edgeRatio > 1)
+ {
+ continue;
+ }
+
+ // we have a collision!
+ if (!foundCollision || movementRatio < shortestMovementRatio) // I think the second condition never gets called because the movementRatio loop
+ // would already continue if the movementRatio was below 0 (which is the shortestMovementRatio)
+ {
+ // if a collision with a passable object is detected (e.g. a haptic rail) and the handle is not within the bounds of the colliding object,
+ // discard the collision and continue
+ auto ob = indexedEdge.m_obstacle;
+ if (ob->passable && !ob->contains(targetPoint))
+ {
+ continue;
+ }
+ foundCollision = true;
+ if (!ob->passable){
+ numCollisions++;
+ }
+ shortestMovementRatio = movementRatio;
+ closestEdgeFirst = edgeFirst;
+ closestEdgeFirstMinusSecond = firstMinusSecond;
+ }
+ }
+
+ // calculate new god object position
+ if (foundCollision)
+ {
+ m_processingObstacleCollision = true;
+
+ // god object slides along the colliding edge according to the handle movement but with tethered speed
+
+ if (m_tethered) {
+ // if the movement is tethered the targetPoint can not be further away from the current position than the outer tether radius
+ const Vector2D movementVector = targetPoint - currentPosition;
+ double movementLength = min(m_tetherOuterRadius, movementVector.length());
+ targetPoint = currentPosition + (movementVector.normalize() * movementLength);
+ }
+
+ auto perpendicular = Vector2D(
+ -closestEdgeFirstMinusSecond.y,
+ closestEdgeFirstMinusSecond.x);
+ auto resolveRatio =
+ -Vector2D::determinant(
+ closestEdgeFirstMinusSecond,
+ closestEdgeFirst - targetPoint) /
+ Vector2D::determinant(
+ closestEdgeFirstMinusSecond,
+ perpendicular);
+ auto resolveVec = perpendicular * resolveRatio;
+ auto resolveLength = resolveVec.length();
+ // c_resolveDistance is super small --> we need to add a tiny padding between the godobject and the edge so that it's not getting stuck in the edge
+ targetPoint = targetPoint - (resolveVec * ((resolveLength + c_resolveDistance) / resolveLength));
+
+
+ // check for the new point if there is another collision with any other edge
+ m_possibleCollisions->clear();
+ hashtable().getPossibleCollisions(
+ Edge(currentPosition, targetPoint), m_possibleCollisions);
+ }
+ // there can be multiple collisions, that's why we have to loop as well over the other possible collisions
+ } while (foundCollision);
+ m_numCollisions = numCollisions;
+ return targetPoint;
+}
+
+void GodObject::createObstacle(uint16_t id, std::vector points, bool passable)
+{
+ // create obstacle or passable obstacle
+ auto ob = new Obstacle(points, passable);
+ portENTER_CRITICAL(&m_obstacleMutex);
+ m_obstacles.emplace(id, ob);
+ portEXIT_CRITICAL(&m_obstacleMutex);
+}
+
+void GodObject::createRail(uint16_t id, std::vector points, double displacement)
+{
+ portENTER_CRITICAL(&m_obstacleMutex);
+ Rail* rail = new Rail(points, displacement);
+ m_obstacles.emplace(id, rail);
+ portEXIT_CRITICAL(&m_obstacleMutex);
+ return;
+
+}
+
+void GodObject::addToObstacle(uint16_t id, std::vector points)
+{
+ auto it = m_obstacles.find(id);
+ if (it != m_obstacles.end())
+ {
+ portENTER_CRITICAL(&m_obstacleMutex);
+ m_obstacles.at(id)->add(points);
+ portEXIT_CRITICAL(&m_obstacleMutex);
+ }
+}
+
+void GodObject::removeObstacle(uint16_t id)
+{
+ enableObstacle(id, false);
+ m_actionQueue.push_back(new GodObjectAction(GO_REMOVE_OBSTACLE, id));
+}
+
+void GodObject::enableObstacle(uint16_t id, bool enable)
+{
+ auto it = m_obstacles.find(id);
+ if (it != m_obstacles.end())
+ {
+ portENTER_CRITICAL(&m_obstacleMutex);
+ if (enable != it->second->enabled())
+ {
+ const auto edges = it->second->getIndexedEdges();
+ const auto action = enable ? HT_ENABLE_EDGE : HT_DISABLE_EDGE;
+ for (const auto& edge : edges)
+ {
+ m_actionQueue.push_back(new GodObjectAction(
+ action,
+ new AnnotatedEdge(
+ new IndexedEdge(edge.m_obstacle, edge.m_index),
+ new Edge(edge.getEdge()))));
+ }
+ }
+ it->second->enable(enable);
+ portEXIT_CRITICAL(&m_obstacleMutex);
+ }
+}
+
+Vector2D GodObject::getPosition()
+{
+ return m_position;
+}
+
+Vector2D GodObject::getActiveForce()
+{
+ return m_activeForce;
+}
+
+bool GodObject::getProcessingObstacleCollision()
+{
+ return m_processingObstacleCollision;
+}
+
+bool GodObject::getDoneColliding()
+{
+ return m_doneColliding;
+}
+
+bool GodObject::tethered()
+{
+ return m_tethered;
+}
+
+void GodObject::setSpeedControl(bool active, double tetherFactor, double innerTetherRadius, double outerTetherRadius, OutOfTetherStrategy strategy, bool pockEnabled)
+{
+ m_tethered = active;
+ m_tetherFactor = tetherFactor;
+ m_tetherInnerRadius = innerTetherRadius;
+ m_tetherOuterRadius = outerTetherRadius;
+ m_tetherStrategy = strategy;
+ m_tetherPockEnabled = pockEnabled;
+}
diff --git a/firmware/09 god object/firmware/src/physics/hashtable.cpp b/firmware/haptics/BIS week7/firmware/src/physics/hashtable.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/physics/hashtable.cpp
rename to firmware/haptics/BIS week7/firmware/src/physics/hashtable.cpp
diff --git a/firmware/09 god object/firmware/src/physics/indexedEdge.cpp b/firmware/haptics/BIS week7/firmware/src/physics/indexedEdge.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/physics/indexedEdge.cpp
rename to firmware/haptics/BIS week7/firmware/src/physics/indexedEdge.cpp
diff --git a/firmware/09 god object/firmware/src/physics/obstacle.cpp b/firmware/haptics/BIS week7/firmware/src/physics/obstacle.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/physics/obstacle.cpp
rename to firmware/haptics/BIS week7/firmware/src/physics/obstacle.cpp
diff --git a/firmware/09 god object/firmware/src/physics/pantoPhysics.cpp b/firmware/haptics/BIS week7/firmware/src/physics/pantoPhysics.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/physics/pantoPhysics.cpp
rename to firmware/haptics/BIS week7/firmware/src/physics/pantoPhysics.cpp
diff --git a/firmware/09 god object/firmware/src/physics/rail.cpp b/firmware/haptics/BIS week7/firmware/src/physics/rail.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/physics/rail.cpp
rename to firmware/haptics/BIS week7/firmware/src/physics/rail.cpp
diff --git a/firmware/haptics/BIS week7/firmware/src/physicsMain.cpp b/firmware/haptics/BIS week7/firmware/src/physicsMain.cpp
new file mode 100644
index 0000000..2eedae2
--- /dev/null
+++ b/firmware/haptics/BIS week7/firmware/src/physicsMain.cpp
@@ -0,0 +1,153 @@
+#include "physicsMain.hpp"
+
+#include "hardware/panto.hpp"
+#include "hardware/spiEncoderChain.hpp"
+#include "physics/pantoPhysics.hpp"
+#include "tasks/taskRegistry.hpp"
+#include "utils/performanceMonitor.hpp"
+#include "utils/framerateLimiter.hpp"
+#include "utils/serial.hpp"
+
+FramerateLimiter spiErrorLimiter = FramerateLimiter::fromSeconds(1);
+
+#ifdef LINKAGE_ENCODER_USE_SPI
+SPIEncoderChain* spi;
+#endif
+
+void physicsSetup()
+{
+ #ifdef LINKAGE_ENCODER_USE_SPI
+ spi = new SPIEncoderChain(numberOfSpiEncoders);
+ #endif
+
+ for (auto i = 0; i < pantoCount; ++i)
+ {
+ pantos.emplace_back(i);
+ }
+ delay(1000);
+
+ xTaskNotifyGive(Tasks.at("I/O").getHandle());
+
+ #ifdef LINKAGE_ENCODER_USE_SPI
+ std::vector startPositions(numberOfSpiEncoders);
+ #endif
+
+ EEPROM.begin(sizeof(uint32_t)*numberOfSpiEncoders);
+
+ //calibrateEncoders; Comment if not needed
+ // for (auto i = 0; i < pantoCount; ++i)
+ // { pantos[i].calibrateEncoders(i);}
+
+ for (auto i = 0; i < pantoCount; ++i)
+ {
+ pantos[i].calibrationEnd(); //calibrating only handle pulse encoder
+ #ifdef LINKAGE_ENCODER_USE_SPI
+ for (auto j = 0; j < 3; ++j) // three encoders
+ {
+ auto index = encoderSpiIndex[i * 3 + j];
+ if(index != 0xffffffff) // excluding it / me handle.
+ {
+ startPositions[index] =
+ ((uint16_t)(pantos[i].getActuationAngle(j) /
+ (TWO_PI) *
+ encoderSteps[i * 3 + j]) & 0x3fff);
+
+ pantos[i].setAngleAccessor(j, spi->getAngleAccessor(index));
+ }
+ }
+ #endif
+ }
+ #ifdef LINKAGE_ENCODER_USE_SPI
+ spi->setPosition(startPositions);
+ #endif
+
+ for (unsigned char i = 0; i < pantoCount; ++i)
+ {
+ pantoPhysics.emplace_back(&pantos[i]);
+ }
+}
+
+void physicsLoop()
+{
+ PERFMON_START("[a] Read encoders");
+ // PERFMON_START("[aa] Query SPI");
+ #ifdef LINKAGE_ENCODER_USE_SPI
+ spi->update();
+ #endif
+ // PERFMON_STOP("[aa] Query SPI");
+
+ // PERFMON_START("[ab] Calculation loop");
+ for (auto i = 0; i < pantoCount; ++i)
+ {
+ // PERFMON_START("[aba] Actually read");
+ pantos[i].readEncoders();
+ // PERFMON_STOP("[aba] Actually read");
+ PERFMON_START("[abb] Calc fwd kinematics");
+ pantos[i].forwardKinematics();
+ PERFMON_STOP("[abb] Calc fwd kinematics");
+ }
+ // PERFMON_STOP("[ab] Calculation loop");
+ PERFMON_STOP("[a] Read encoders");
+
+ PERFMON_START("[b] Calculate physics");
+ for (auto i = 0; i < pantoCount; ++i)
+ {
+ pantoPhysics[i].step();
+ }
+ PERFMON_STOP("[b] Calculate physics");
+
+ PERFMON_START("[c] Actuate motors");
+ for (auto i = 0; i < pantoCount; ++i)
+ {
+ pantos[i].actuateMotors();
+ }
+ PERFMON_STOP("[c] Actuate motors");
+
+ if(spiErrorLimiter.step()) {
+ // DPSerial::sendQueuedDebugLog("SPI Errors: %i out of %i requests", spi->getErrors(), spi->getRequests());
+ // for(int i=0; i < 2; i++){
+ // DPSerial::sendQueuedDebugLog("Encoder Errors panto[0][%i]: %i out of %i requests",i,
+ // pantos[0].getEncoderErrorCounts(i), pantos[0].getEncoderRequestsCounts(i));
+ // }
+ // for(int i=0; i < 2; i++){
+ // DPSerial::sendQueuedDebugLog("Encoder Errors panto[1][%i]: %i out of %i requests",i,
+ // pantos[1].getEncoderErrorCounts(i), pantos[1].getEncoderRequestsCounts(i));
+ // }
+ // spi->resetErrors();
+ }
+
+ PERFMON_START("[d] Calibrate Pantos");
+ bool flag = false;
+ for(auto i = 0; i < pantoCount; ++i){
+ if(pantos[i].getCalibrationState()){
+ flag = true;
+ break;
+ }
+ }
+ if(flag){
+ #ifdef LINKAGE_ENCODER_USE_SPI
+ std::vector startPositions(numberOfSpiEncoders);
+ #endif
+ for (auto i = 0; i < pantoCount; ++i)
+ {
+ pantos[i].calibrationEnd();
+ #ifdef LINKAGE_ENCODER_USE_SPI
+ for (auto j = 0; j < 3; ++j) // three encoders
+ {
+ auto index = encoderSpiIndex[i * 3 + j];
+ if(index != 0xffffffff) // excluding it / me handle.
+ {
+ startPositions[index] =
+ ((uint16_t)(pantos[i].getActuationAngle(j) /
+ (TWO_PI) *
+ encoderSteps[i * 3 + j]) & 0x3fff);
+ }
+ }
+ #endif
+ }
+ #ifdef LINKAGE_ENCODER_USE_SPI
+ spi->setPosition(startPositions);
+ #endif
+ }
+ PERFMON_STOP("[d] Calibrate Pantos");
+}
diff --git a/firmware/09 god object/firmware/src/tasks/task.cpp b/firmware/haptics/BIS week7/firmware/src/tasks/task.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/tasks/task.cpp
rename to firmware/haptics/BIS week7/firmware/src/tasks/task.cpp
diff --git a/firmware/09 god object/firmware/src/tasks/taskRegistry.cpp b/firmware/haptics/BIS week7/firmware/src/tasks/taskRegistry.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/tasks/taskRegistry.cpp
rename to firmware/haptics/BIS week7/firmware/src/tasks/taskRegistry.cpp
diff --git a/firmware/09 god object/firmware/src/utils/crashDump.cpp b/firmware/haptics/BIS week7/firmware/src/utils/crashDump.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/utils/crashDump.cpp
rename to firmware/haptics/BIS week7/firmware/src/utils/crashDump.cpp
diff --git a/firmware/09 god object/firmware/src/utils/framerateLimiter.cpp b/firmware/haptics/BIS week7/firmware/src/utils/framerateLimiter.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/utils/framerateLimiter.cpp
rename to firmware/haptics/BIS week7/firmware/src/utils/framerateLimiter.cpp
diff --git a/firmware/09 god object/firmware/src/utils/performanceMonitor.cpp b/firmware/haptics/BIS week7/firmware/src/utils/performanceMonitor.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/utils/performanceMonitor.cpp
rename to firmware/haptics/BIS week7/firmware/src/utils/performanceMonitor.cpp
diff --git a/firmware/09 god object/firmware/src/utils/serial.cpp b/firmware/haptics/BIS week7/firmware/src/utils/serial.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/utils/serial.cpp
rename to firmware/haptics/BIS week7/firmware/src/utils/serial.cpp
diff --git a/firmware/09 god object/firmware/src/utils/vector.cpp b/firmware/haptics/BIS week7/firmware/src/utils/vector.cpp
similarity index 100%
rename from firmware/09 god object/firmware/src/utils/vector.cpp
rename to firmware/haptics/BIS week7/firmware/src/utils/vector.cpp
diff --git a/firmware/09 god object/utils/backtrace/backtrace.sh b/firmware/haptics/BIS week7/utils/backtrace/backtrace.sh
similarity index 100%
rename from firmware/09 god object/utils/backtrace/backtrace.sh
rename to firmware/haptics/BIS week7/utils/backtrace/backtrace.sh
diff --git a/firmware/09 god object/utils/protocol/include/protocol/header.hpp b/firmware/haptics/BIS week7/utils/protocol/include/protocol/header.hpp
similarity index 100%
rename from firmware/09 god object/utils/protocol/include/protocol/header.hpp
rename to firmware/haptics/BIS week7/utils/protocol/include/protocol/header.hpp
diff --git a/firmware/09 god object/utils/protocol/include/protocol/messageType.hpp b/firmware/haptics/BIS week7/utils/protocol/include/protocol/messageType.hpp
similarity index 100%
rename from firmware/09 god object/utils/protocol/include/protocol/messageType.hpp
rename to firmware/haptics/BIS week7/utils/protocol/include/protocol/messageType.hpp
diff --git a/firmware/09 god object/utils/protocol/include/protocol/protocol.hpp b/firmware/haptics/BIS week7/utils/protocol/include/protocol/protocol.hpp
similarity index 100%
rename from firmware/09 god object/utils/protocol/include/protocol/protocol.hpp
rename to firmware/haptics/BIS week7/utils/protocol/include/protocol/protocol.hpp
diff --git a/firmware/09 god object/utils/protocol/src/protocol/messageType.cpp b/firmware/haptics/BIS week7/utils/protocol/src/protocol/messageType.cpp
similarity index 100%
rename from firmware/09 god object/utils/protocol/src/protocol/messageType.cpp
rename to firmware/haptics/BIS week7/utils/protocol/src/protocol/messageType.cpp
diff --git a/firmware/09 god object/utils/protocol/src/protocol/protocol.cpp b/firmware/haptics/BIS week7/utils/protocol/src/protocol/protocol.cpp
similarity index 100%
rename from firmware/09 god object/utils/protocol/src/protocol/protocol.cpp
rename to firmware/haptics/BIS week7/utils/protocol/src/protocol/protocol.cpp
diff --git a/firmware/09 god object/utils/scripts/generateHardwareConfig.js b/firmware/haptics/BIS week7/utils/scripts/generateHardwareConfig.js
similarity index 100%
rename from firmware/09 god object/utils/scripts/generateHardwareConfig.js
rename to firmware/haptics/BIS week7/utils/scripts/generateHardwareConfig.js
diff --git a/firmware/09 god object/utils/scripts/run.js b/firmware/haptics/BIS week7/utils/scripts/run.js
similarity index 100%
rename from firmware/09 god object/utils/scripts/run.js
rename to firmware/haptics/BIS week7/utils/scripts/run.js
diff --git a/firmware/09 god object/utils/scripts/tools.js b/firmware/haptics/BIS week7/utils/scripts/tools.js
similarity index 100%
rename from firmware/09 god object/utils/scripts/tools.js
rename to firmware/haptics/BIS week7/utils/scripts/tools.js
diff --git a/firmware/09 god object/utils/serial/CMakeLists.txt b/firmware/haptics/BIS week7/utils/serial/CMakeLists.txt
similarity index 100%
rename from firmware/09 god object/utils/serial/CMakeLists.txt
rename to firmware/haptics/BIS week7/utils/serial/CMakeLists.txt
diff --git a/firmware/09 god object/utils/serial/binding.gyp b/firmware/haptics/BIS week7/utils/serial/binding.gyp
similarity index 100%
rename from firmware/09 god object/utils/serial/binding.gyp
rename to firmware/haptics/BIS week7/utils/serial/binding.gyp
diff --git a/firmware/09 god object/utils/serial/include/crashAnalyzer.hpp b/firmware/haptics/BIS week7/utils/serial/include/crashAnalyzer.hpp
similarity index 100%
rename from firmware/09 god object/utils/serial/include/crashAnalyzer.hpp
rename to firmware/haptics/BIS week7/utils/serial/include/crashAnalyzer.hpp
diff --git a/firmware/09 god object/utils/serial/include/libInterface.hpp b/firmware/haptics/BIS week7/utils/serial/include/libInterface.hpp
similarity index 100%
rename from firmware/09 god object/utils/serial/include/libInterface.hpp
rename to firmware/haptics/BIS week7/utils/serial/include/libInterface.hpp
diff --git a/firmware/09 god object/utils/serial/include/node.hpp b/firmware/haptics/BIS week7/utils/serial/include/node.hpp
similarity index 100%
rename from firmware/09 god object/utils/serial/include/node.hpp
rename to firmware/haptics/BIS week7/utils/serial/include/node.hpp
diff --git a/firmware/09 god object/utils/serial/include/packet.hpp b/firmware/haptics/BIS week7/utils/serial/include/packet.hpp
similarity index 100%
rename from firmware/09 god object/utils/serial/include/packet.hpp
rename to firmware/haptics/BIS week7/utils/serial/include/packet.hpp
diff --git a/firmware/09 god object/utils/serial/include/serial.hpp b/firmware/haptics/BIS week7/utils/serial/include/serial.hpp
similarity index 100%
rename from firmware/09 god object/utils/serial/include/serial.hpp
rename to firmware/haptics/BIS week7/utils/serial/include/serial.hpp
diff --git a/firmware/09 god object/utils/serial/include/serial_export.hpp b/firmware/haptics/BIS week7/utils/serial/include/serial_export.hpp
similarity index 100%
rename from firmware/09 god object/utils/serial/include/serial_export.hpp
rename to firmware/haptics/BIS week7/utils/serial/include/serial_export.hpp
diff --git a/firmware/09 god object/utils/serial/include/standalone.hpp b/firmware/haptics/BIS week7/utils/serial/include/standalone.hpp
similarity index 100%
rename from firmware/09 god object/utils/serial/include/standalone.hpp
rename to firmware/haptics/BIS week7/utils/serial/include/standalone.hpp
diff --git a/firmware/09 god object/utils/serial/src/cppLib/lib.cpp b/firmware/haptics/BIS week7/utils/serial/src/cppLib/lib.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/cppLib/lib.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/cppLib/lib.cpp
diff --git a/firmware/09 god object/utils/serial/src/crashAnalyzer/analyze.cpp b/firmware/haptics/BIS week7/utils/serial/src/crashAnalyzer/analyze.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/crashAnalyzer/analyze.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/crashAnalyzer/analyze.cpp
diff --git a/firmware/09 god object/utils/serial/src/crashAnalyzer/buffer.cpp b/firmware/haptics/BIS week7/utils/serial/src/crashAnalyzer/buffer.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/crashAnalyzer/buffer.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/crashAnalyzer/buffer.cpp
diff --git a/firmware/09 god object/utils/serial/src/node/main.cpp b/firmware/haptics/BIS week7/utils/serial/src/node/main.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/node/main.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/node/main.cpp
diff --git a/firmware/09 god object/utils/serial/src/node/poll.cpp b/firmware/haptics/BIS week7/utils/serial/src/node/poll.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/node/poll.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/node/poll.cpp
diff --git a/firmware/09 god object/utils/serial/src/node/receiveHelpers.cpp b/firmware/haptics/BIS week7/utils/serial/src/node/receiveHelpers.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/node/receiveHelpers.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/node/receiveHelpers.cpp
diff --git a/firmware/09 god object/utils/serial/src/node/send.cpp b/firmware/haptics/BIS week7/utils/serial/src/node/send.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/node/send.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/node/send.cpp
diff --git a/firmware/09 god object/utils/serial/src/node/sendHelpers.cpp b/firmware/haptics/BIS week7/utils/serial/src/node/sendHelpers.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/node/sendHelpers.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/node/sendHelpers.cpp
diff --git a/firmware/09 god object/utils/serial/src/node/setup.cpp b/firmware/haptics/BIS week7/utils/serial/src/node/setup.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/node/setup.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/node/setup.cpp
diff --git a/firmware/09 god object/utils/serial/src/serial/packet.cpp b/firmware/haptics/BIS week7/utils/serial/src/serial/packet.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/serial/packet.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/serial/packet.cpp
diff --git a/firmware/09 god object/utils/serial/src/serial/shared.cpp b/firmware/haptics/BIS week7/utils/serial/src/serial/shared.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/serial/shared.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/serial/shared.cpp
diff --git a/firmware/09 god object/utils/serial/src/serial/unix.cpp b/firmware/haptics/BIS week7/utils/serial/src/serial/unix.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/serial/unix.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/serial/unix.cpp
diff --git a/firmware/09 god object/utils/serial/src/serial/win.cpp b/firmware/haptics/BIS week7/utils/serial/src/serial/win.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/serial/win.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/serial/win.cpp
diff --git a/firmware/09 god object/utils/serial/src/standalone/main.cpp b/firmware/haptics/BIS week7/utils/serial/src/standalone/main.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/standalone/main.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/standalone/main.cpp
diff --git a/firmware/09 god object/utils/serial/src/standalone/standalone.cpp b/firmware/haptics/BIS week7/utils/serial/src/standalone/standalone.cpp
similarity index 100%
rename from firmware/09 god object/utils/serial/src/standalone/standalone.cpp
rename to firmware/haptics/BIS week7/utils/serial/src/standalone/standalone.cpp
diff --git a/firmware/09 god object/utils/serial/unity/Serial.cs b/firmware/haptics/BIS week7/utils/serial/unity/Serial.cs
similarity index 100%
rename from firmware/09 god object/utils/serial/unity/Serial.cs
rename to firmware/haptics/BIS week7/utils/serial/unity/Serial.cs
diff --git a/firmware/09 god object/utils/serial/unity/linux.sh b/firmware/haptics/BIS week7/utils/serial/unity/linux.sh
similarity index 100%
rename from firmware/09 god object/utils/serial/unity/linux.sh
rename to firmware/haptics/BIS week7/utils/serial/unity/linux.sh
diff --git a/firmware/09 god object/utils/serial/unity/mac.sh b/firmware/haptics/BIS week7/utils/serial/unity/mac.sh
similarity index 100%
rename from firmware/09 god object/utils/serial/unity/mac.sh
rename to firmware/haptics/BIS week7/utils/serial/unity/mac.sh
diff --git a/firmware/09 god object/utils/serial/unity/win.bat b/firmware/haptics/BIS week7/utils/serial/unity/win.bat
similarity index 100%
rename from firmware/09 god object/utils/serial/unity/win.bat
rename to firmware/haptics/BIS week7/utils/serial/unity/win.bat
diff --git a/firmware/haptics/force field/firmware/.gitignore b/firmware/haptics/force field/firmware/.gitignore
new file mode 100644
index 0000000..6106fab
--- /dev/null
+++ b/firmware/haptics/force field/firmware/.gitignore
@@ -0,0 +1,4 @@
+.vscode
+.pio
+.pioenvs
+.piolibdeps
diff --git a/firmware/haptics/force field/firmware/.idea/.gitignore b/firmware/haptics/force field/firmware/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/firmware/haptics/force field/firmware/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/firmware/haptics/force field/firmware/.idea/misc.xml b/firmware/haptics/force field/firmware/.idea/misc.xml
new file mode 100644
index 0000000..d858eb1
--- /dev/null
+++ b/firmware/haptics/force field/firmware/.idea/misc.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/firmware/haptics/force field/firmware/.idea/vcs.xml b/firmware/haptics/force field/firmware/.idea/vcs.xml
new file mode 100644
index 0000000..8aefe6c
--- /dev/null
+++ b/firmware/haptics/force field/firmware/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/firmware/haptics/force field/firmware/include/config/config.hpp b/firmware/haptics/force field/firmware/include/config/config.hpp
new file mode 100644
index 0000000..ab0218a
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/config/config.hpp
@@ -0,0 +1,103 @@
+/*
+ * This file is generated by GenerateHardwareConfig.js and ignored in git. Any changes you apply will *not* persist.
+ *
+ * config.hpp contains hardware specific data like the pantograph size and the I/O pins.
+ * It is generated by GenerateHardwareConfig.js using the hardware specifications found in the Hardware dir.
+ *
+ * In order to avoid additional checks, unused data is rerouted to invalid pins instead of filtering all calls.
+ * For the current configuration, this dummy pin is 40. Any assignments to this pin will be ignored, all reads from this pin will return 0.
+ */
+
+#pragma once
+
+#include
+
+const uint8_t configHash[] = {0x8F, 0x37, 0xA2, 0x7A, 0x29, 0xDA, 0x7D, 0xB4, 0xBB, 0x54, 0x0F, 0x13, 0x43, 0x71, 0xBC, 0xE9};
+const float opMinDist = 65,
+ opMaxDist = 210,
+ opAngle = 2.2;
+extern float forceFactor;
+const uint8_t pantoCount = 2;
+const uint8_t dummyPin = 40;
+#define LINKAGE_ENCODER_USE_SPI
+const uint32_t numberOfSpiEncoders = 4;
+const float linkageBaseX[] = {
+ -23.7, 61.1, 0, -61.1, 23.7, 0
+};
+const float linkageBaseY[] = {
+ 0, 0, 0, 0, 0, 0
+};
+const float linkageInnerLength[] = {
+ 95.07, 57.71, 0, 57.71, 95.07, 0
+};
+const float linkageOuterLength[] = {
+ 119.79, 119.79, 0, 119.79, 119.79, 0
+};
+const uint8_t linkageHandleMount[] = {
+ 0, 0, 1, 0, 0, 0
+};
+const float motorPowerLimit[] = {
+ 0.2, 0.2, 0.2, 0.2, 0.2, 0.2
+};
+const float motor_powerLimitForce[] = {
+ 0.6, 0.6, 0.2, 0.6, 0.6, 0.2
+};
+extern float pidFactor[6][3];
+const float forceP = 0.375;
+const float forceI = 0;
+const float forceD = 0;
+const float forcePidFactor[2][3] = {
+ {forceP, forceI, forceD}, {forceP, forceI, forceD}
+};
+const uint8_t motorPwmPin[] = {
+ 40, 40, 25, 40, 40, 23
+};
+const uint8_t motorPwmPinForwards[] = {
+ 16, 2, 40, 22, 19, 40
+};
+const uint8_t motorPwmPinBackwards[] = {
+ 4, 17, 40, 21, 18, 40
+};
+const uint8_t motorDirAPin[] = {
+ 40, 40, 32, 40, 40, 26
+};
+const uint8_t motorDirBPin[] = {
+ 40, 40, 40, 40, 40, 40
+};
+const bool motorFlipped[] = {
+ false, false, true, false, false, true
+};
+const uint8_t encoderAPin[] = {
+ 40, 40, 35, 40, 40, 36
+};
+const uint8_t encoderBPin[] = {
+ 40, 40, 34, 40, 40, 39
+};
+const uint8_t encoderIndexPin[] = {
+ 40, 40, 40, 40, 40, 40
+};
+const uint32_t encoderSteps[] = {
+ 16384, 16384, 260, 16384, 16384, 260
+};
+const uint32_t encoderSpiIndex[] = {
+ 3, 2, 4294967295, 0, 1, 4294967295
+};
+const float encoderFlipped[] = {
+ 1, 1, 1, -1, -1, -1
+};
+const float setupAngle[] = {
+ -0.5, 0.001, 0, -0.5, 0.001, 0
+};
+constexpr float rangeMinX = -180;
+constexpr float rangeMinY = -205;
+constexpr float rangeMaxX = 180;
+constexpr float rangeMaxY = 5;
+constexpr uint32_t hashtableMaxMemory = 100000;
+constexpr uint32_t hashtableUsedMemory = 98532;
+constexpr uint32_t hashtableMaxCells = 8333;
+constexpr uint32_t hashtableNumCells = 8211;
+constexpr uint32_t hashtableStepsX = 119;
+constexpr uint32_t hashtableStepsY = 69;
+constexpr double hashtableStepSizeX = 3.0252100840336134;
+constexpr double hashtableStepSizeY = 3.0434782608695654;
+const uint32_t obstacleChangesPerFrame = 1;
\ No newline at end of file
diff --git a/firmware/haptics/force field/firmware/include/hardware/angleAccessor.hpp b/firmware/haptics/force field/firmware/include/hardware/angleAccessor.hpp
new file mode 100644
index 0000000..fc7e636
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/hardware/angleAccessor.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include
+
+typedef std::function AngleAccessor;
diff --git a/firmware/haptics/force field/firmware/include/hardware/panto.hpp b/firmware/haptics/force field/firmware/include/hardware/panto.hpp
new file mode 100644
index 0000000..143d308
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/hardware/panto.hpp
@@ -0,0 +1,126 @@
+#pragma once
+
+#include
+
+#include "config/config.hpp"
+#include "hardware/angleAccessor.hpp"
+#include "utils/vector.hpp"
+#include
+
+// make sure results are in range -270° ~ 0° ~ +90°
+#define ensureAngleRange(angle) \
+ angle > HALF_PI ? \
+ angle - TWO_PI : \
+ angle < -(PI + HALF_PI) ? \
+ angle + TWO_PI : \
+ angle
+
+class Panto
+{
+private:
+ static const uint16_t c_ledcFrequency = 20000;
+ static const uint16_t c_ledcResolution = 12;
+ static const uint16_t PWM_MAX = 4095; // (2^12)-1
+ static const uint8_t c_dofCount = 3;
+ const uint8_t c_localLeftIndex = 0;
+ const uint8_t c_localRightIndex = 1;
+ const uint8_t c_localHandleIndex = 2;
+
+ const uint8_t c_pantoIndex;
+ const uint8_t c_globalIndexOffset;
+ const uint8_t c_globalLeftIndex;
+ const uint8_t c_globalRightIndex;
+ const uint8_t c_globalHandleIndex;
+ const float c_leftInnerLength;
+ const float c_rightInnerLength;
+ const float c_leftOuterLength;
+ const float c_rightOuterLength;
+ const float c_leftInnerLengthDoubled;
+ const float c_rightInnerLengthDoubled;
+ const float c_leftInnerLengthSquared;
+ const float c_rightInnerLengthSquared;
+ const float c_leftOuterLengthSquared;
+ const float c_rightOuterLengthSquared;
+ const float c_leftInnerLengthSquaredMinusLeftOuterLengthSquared;
+ const float c_rightInnerLengthSquaredMinusRightOuterLengthSquared;
+ const float c_leftOuterLengthSquaredMinusRightOuterLengthSquared;
+ const bool c_handleMountedOnRightArm;
+ const float c_leftBaseX;
+ const float c_leftBaseY;
+ const float c_rightBaseX;
+ const float c_rightBaseY;
+
+ #ifdef LINKAGE_ENCODER_USE_SPI
+ AngleAccessor m_angleAccessors[2];
+ #endif
+ Encoder* m_encoder[c_dofCount];
+ float m_actuationAngle[c_dofCount];
+ float m_previousAngle[c_dofCount];
+ float m_previousAngles[c_dofCount][5];
+ float m_targetAngle[c_dofCount];
+ float m_previousDiff[c_dofCount];
+ float m_integral[c_dofCount];
+ uint32_t m_prevTime = 0;
+
+ int m_previousAnglesCount = 0;
+ int m_encoderErrorCount = 0;
+ int m_encoderErrorCounts[4] = {0,0,0,0};
+ int m_encoderRequestCount = 0;
+ int m_encoderRequestCounts[4] = {0,0,0,0};
+ float m_leftInnerAngle = 0;
+ float m_rightInnerAngle = 0;
+ float m_pointingAngle = 0;
+ float m_handleX = 0;
+ float m_handleY = 0;
+ float m_targetX = 0;
+ float m_targetY = 0;
+ float m_startX = 0;
+ float m_startY = 0;
+ float m_filteredX = 0;
+ float m_filteredY = 0;
+ float m_tweeningValue = 0.0f;
+ float m_tweeningStep = 0.00001f;
+ float m_tweeningSpeed = 1.0f;
+ uint32_t m_tweeningPrevtime = 0;
+ float m_dt = 0.0001f;
+ float delta = 0.01;
+ float velocity = 1.0f;
+ bool m_isforceRendering = false;
+ bool m_inTransition = false;
+ float m_jacobian[2][2] = {{0.0, 0.0}, {0.0, 0.0}};
+ bool m_isFrozen = false;
+ bool m_isCalibrating = false;
+
+ void inverseKinematics();
+ void setMotor(
+ const uint8_t& localIndex, const bool& dir, const float& power);
+ void disengageMotors();
+public:
+ Panto(uint8_t pantoIndex);
+ float getActuationAngle(const uint8_t index) const;
+ Vector2D getPosition() const;
+ float getRotation() const;
+ void setAngleAccessor(const uint8_t index, const AngleAccessor accessor);
+ void setTarget(const Vector2D target, const bool isForceRendering);
+ void setSpeed(const float speed);
+ void setRotation(const float rotation);
+ bool getCalibrationState();
+ void calibrateEncoders();
+ void calibratePanto();
+ void calibrationEnd();
+ void resetActuationAngle();
+ void readEncoders();
+ void forwardKinematics();
+ void actuateMotors();
+ int getEncoderErrorCount();
+ int getEncoderRequests();
+ int getEncoderErrorCounts(int i);
+ int getEncoderRequestsCounts(int i);
+ uint8_t getPantoIndex();
+ bool getInTransition();
+ void setInTransition(bool inTransition);
+ bool getIsFrozen();
+ void setIsFrozen(bool isFrozen);
+};
+
+extern std::vector pantos;
\ No newline at end of file
diff --git a/firmware/haptics/force field/firmware/include/hardware/spiCommands.hpp b/firmware/haptics/force field/firmware/include/hardware/spiCommands.hpp
new file mode 100644
index 0000000..4f80dbe
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/hardware/spiCommands.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include
+
+namespace SPICommands
+{
+ extern const uint16_t c_readAngle;
+ extern const uint16_t c_clearError;
+ extern const uint16_t c_nop;
+ extern const uint16_t c_highZeroRead;
+ extern const uint16_t c_lowZeroRead;
+ extern const uint16_t c_highZeroWrite;
+ extern const uint16_t c_lowZeroWrite;
+};
diff --git a/firmware/haptics/force field/firmware/include/hardware/spiEncoder.hpp b/firmware/haptics/force field/firmware/include/hardware/spiEncoder.hpp
new file mode 100644
index 0000000..21e9575
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/hardware/spiEncoder.hpp
@@ -0,0 +1,19 @@
+#pragma once
+
+#include
+
+#include "hardware/spiPacket.hpp"
+
+class SPIEncoder
+{
+ friend class SPIEncoderChain;
+private:
+ SPIPacket m_lastPacket;
+ uint16_t m_lastValidAngle;
+ SPIClass* m_spi;
+ SPIEncoder() = default;
+ SPIEncoder(SPIClass* spi);
+ void transfer(uint16_t transmisson);
+public:
+ uint32_t getAngle();
+};
diff --git a/firmware/haptics/force field/firmware/include/hardware/spiEncoderChain.hpp b/firmware/haptics/force field/firmware/include/hardware/spiEncoderChain.hpp
new file mode 100644
index 0000000..0b5bb86
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/hardware/spiEncoderChain.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include
+#include
+
+#include "hardware/angleAccessor.hpp"
+#include "hardware/spiEncoder.hpp"
+
+class SPIEncoderChain
+{
+private:
+ SPISettings m_settings;
+ SPIClass m_spi;
+ uint32_t m_numberOfEncoders;
+ std::vector m_encoders;
+ std::vector m_values;
+ std::vector m_zeros;
+ uint32_t errors = 0;
+ uint32_t requests = 0;
+ uint8_t m_maxTries = 4;
+ uint8_t m_currentTry = 0;
+ // static const uint32_t c_hspiSsPin = 15;
+
+ static const uint32_t c_hspiSsPin1 = 15;
+ static const uint32_t c_hspiSsPin2 = 5;
+ static const uint16_t c_nop = 0x0;
+ static const uint16_t c_clearError = 0x4001;
+ static const uint16_t c_readAngle = 0xFFFF;
+ static const uint16_t c_dataMask = 0x3FFF;
+
+ void begin();
+ void end();
+ std::vector getZero();
+ void transfer(uint16_t transmission);
+ void setZero(std::vector newZero);
+public:
+ SPIEncoderChain(uint32_t numberOfEncoders);
+ void update(int channel);
+ void update();
+ void clearError();
+ void setZero();
+ bool needsZero();
+ void wakeUp();
+ void __setZeros();
+ void setPosition(std::vector positions);
+ uint32_t getErrors();
+ uint32_t getRequests();
+ void resetErrors();
+ AngleAccessor getAngleAccessor(uint32_t index);
+};
\ No newline at end of file
diff --git a/firmware/haptics/force field/firmware/include/hardware/spiPacket.hpp b/firmware/haptics/force field/firmware/include/hardware/spiPacket.hpp
new file mode 100644
index 0000000..73750d6
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/hardware/spiPacket.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include
+
+struct SPIPacket
+{
+ bool m_parity;
+ bool m_flag;
+ uint16_t m_data;
+ bool m_valid;
+ uint16_t m_transmission;
+ static const uint16_t c_parityMask = 0x8000;
+ static const uint16_t c_flagMask = 0x4000;
+ static const uint16_t c_dataMask = 0x3FFF;
+ SPIPacket(bool flag, uint16_t data);
+ SPIPacket(uint16_t transmisson);
+ SPIPacket() = default;
+ bool calcParity();
+ bool parityError();
+ bool commandInvalidError();
+ bool framingError();
+};
diff --git a/firmware/haptics/force field/firmware/include/ioMain.hpp b/firmware/haptics/force field/firmware/include/ioMain.hpp
new file mode 100644
index 0000000..1641622
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/ioMain.hpp
@@ -0,0 +1,4 @@
+#pragma once
+
+void ioSetup();
+void ioLoop();
diff --git a/firmware/haptics/force field/firmware/include/physics/annotatedEdge.hpp b/firmware/haptics/force field/firmware/include/physics/annotatedEdge.hpp
new file mode 100644
index 0000000..d2c8370
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/physics/annotatedEdge.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include
+
+struct Edge;
+struct IndexedEdge;
+class Obstacle;
+
+struct AnnotatedEdge
+{
+ IndexedEdge* m_indexedEdge;
+ Edge* m_edge;
+ AnnotatedEdge(IndexedEdge* indexedEdge, Edge* edge);
+ AnnotatedEdge(const AnnotatedEdge& other);
+ void destroy();
+};
diff --git a/firmware/haptics/force field/firmware/include/physics/collider.hpp b/firmware/haptics/force field/firmware/include/physics/collider.hpp
new file mode 100644
index 0000000..5d78845
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/physics/collider.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include
+
+#include "physics/edge.hpp"
+#include "utils/vector.hpp"
+
+class Collider
+{
+protected:
+ std::vector m_points;
+public:
+ Collider(std::vector points);
+ void add(std::vector points);
+ virtual bool contains(Vector2D point);
+ Edge getEdge(uint32_t index);
+};
diff --git a/firmware/haptics/force field/firmware/include/physics/edge.hpp b/firmware/haptics/force field/firmware/include/physics/edge.hpp
new file mode 100644
index 0000000..35b00ff
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/physics/edge.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "utils/vector.hpp"
+
+struct Edge
+{
+ Vector2D m_first;
+ Vector2D m_second;
+ Edge(Vector2D first, Vector2D second) : m_first(first), m_second(second) {};
+ Edge() : m_first(Vector2D()), m_second(Vector2D()) {};
+};
diff --git a/firmware/haptics/force field/firmware/include/physics/godObject.hpp b/firmware/haptics/force field/firmware/include/physics/godObject.hpp
new file mode 100644
index 0000000..919353c
--- /dev/null
+++ b/firmware/haptics/force field/firmware/include/physics/godObject.hpp
@@ -0,0 +1,93 @@
+#pragma once
+
+#include
+#include