diff --git a/auto_sim/.gitignore b/auto_sim/.gitignore new file mode 100644 index 0000000..4c6891f --- /dev/null +++ b/auto_sim/.gitignore @@ -0,0 +1,5 @@ +__pycache__ +build +*.egg-info +labels +.idea \ No newline at end of file diff --git a/auto_sim/.vscode/settings.json b/auto_sim/.vscode/settings.json new file mode 100644 index 0000000..82b6a2f --- /dev/null +++ b/auto_sim/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "python-envs.defaultEnvManager": "ms-python.python:pipenv", + "cmake.sourceDirectory": "C:/Users/jessi/Documents/School/fsae/sim/auto_sim/test_controller_2", + "editor.defaultFormatter": null +} \ No newline at end of file diff --git a/auto_sim/Pipfile b/auto_sim/Pipfile new file mode 100644 index 0000000..9acf776 --- /dev/null +++ b/auto_sim/Pipfile @@ -0,0 +1,18 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +pygame = "*" +numpy = "*" +scipy = "*" +setuptools = "*" +pybind11 = "*" +requests = "*" +casadi = "==3.6.7" + +[dev-packages] + +[requires] +python_version = "3.13" diff --git a/auto_sim/Pipfile.lock b/auto_sim/Pipfile.lock new file mode 100644 index 0000000..1a2f9eb --- /dev/null +++ b/auto_sim/Pipfile.lock @@ -0,0 +1,482 @@ +{ + "_meta": { + "hash": { + "sha256": "99c98440216291c693070c2fd616fd9a9691013b1b74849cdfb39eeefffc7f78" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.13" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "casadi": { + "hashes": [ + "sha256:0012c1951286013ab1c7ab79f21fec7374995085f9067d8cef7873dea062b426", + "sha256:045c1c7fc24bb27398f0ba8979eb6bf07b09525496dc83ee4e75ca037187a6bd", + "sha256:05ef1a87ac6e173cba3762f0ad0ba50c02154317a1135317a23c446a149a2e12", + "sha256:05fedada09ae4f1b8d53194168efa8d88ca878717a9a4e7a2465b6e2aacff805", + "sha256:16042ef095117704312be53389a0f22ab7a0968131db2bf785663d8003957a95", + "sha256:1a676437955fcda10488fea87f78ae64f495a7247825bda476199cdeb5ba0b4d", + "sha256:1a7122f3fd4dca0ed9af72bac398de06e225b291b45c3d89b73a19a3247eeeb5", + "sha256:1ab528f5ea04ef56e2676252cfc3a04023de5d1169578d1873ce403e23fb48d5", + "sha256:1b7467dd5e664a87e03ff118993587d154371a3fb7020ce705ee1045ab561399", + "sha256:1d52d8c11d0125552e10c458d8f33b38cd9a6eb9603405a1df87eb35aae4c93a", + "sha256:21cde87288afebb32a2a035bf6b6a91a025e24ee14aba7a0ae5515707b9887c1", + "sha256:21d5b4ce0f83cfc4ab3b9129bdd7501758457323518069f760cb13a0cefb7fc9", + "sha256:26fea7e80b104698d7c799556ec706ce29748e0e2a045a2ca7eb66032e428929", + "sha256:290e92a7e2f4cecffc229dc196a85855e7dbedf6929eed1850b27e4ad8ad67f0", + "sha256:32ba1335bb0928fd340adc9e21d481d918025072a1f0540cf94093b95f781951", + "sha256:3a51b7731126ca1767accbe6747df7ba0087fc32537ab7e5843db88ab42454e3", + "sha256:4e98668fe6ea0fc8bd9e4189a8f71725acd13c5e748af62b6796bc8fcb71af1d", + "sha256:514b5d2af59c3a60b2a955d9508d5f2c75f05bec1e2f5000043870856e3d41a3", + "sha256:53189e560bcc20e7b10714356c987ae98755e28d5103337fd96bc81632786591", + "sha256:5c252837354ca9da91bb2c9836921213d3972dad6edf516c9c8ef296e71a4f74", + "sha256:636746feeeef755a003b6b13a7fca275a8ad3e1be21f5d78a60e72ecdca9c841", + "sha256:641efda22adc1fab2faeb8cb1eb866619f2240f32fb6a02ae82b7399746cdc2e", + "sha256:65976cabb6f8b5eecd72b346edbc4211cf0c8743c1ab9109ddc0eb0407da5a7e", + "sha256:6b6240fcd207aa154867a09bb830d3067d0e55808fbaef8c4c0e24c55b6905b4", + "sha256:743b6d0070bb0262ec1fd4f840244991ebed2435b3104a5ae6a3bc928d0b31f7", + "sha256:783976f9016ed2e882f00f3dc81a72abd8424fc6e8d322793d4bd3782a37f96d", + "sha256:7d7997a9d9ded13fb974fec62c1b5921c1360910ee01784e5a421e288d10adad", + "sha256:7da27dc03524d56d450880db2cc7f45f075524bc434b0b317e2d80dd76b45d75", + "sha256:7ebcbb566f2a01118bc6db5453876d2a69a2ab56bdcd45f9b5487b6b45cbb1f8", + "sha256:7f65e7444ddb15f521e0dc5d61b2557054e264de1dea8d9990235336d3e80247", + "sha256:8c4b4d0443a07452e7b6e0717ec504ed6a82d5da8bca6798809fb0524499c552", + "sha256:8cefef3e30c36e89df94b94ba19eb3588b960ff713d7631233d3402d34544f47", + "sha256:971cefbe41e6bde88547c0591ab9424ad1efbe81edc6b0c5a54f125ddffadbf1", + "sha256:a5e2bf2311225970c06000c78d9945cb6e2142fb35981426a8eb86ef947a2483", + "sha256:a6c549826a0f46e0ee120581a8ed9b802100040274eb23c3e41ca7e4b5f92555", + "sha256:acddbf6bb05e357c898bcb3253ed106c3be6a0007957ec0231f84cae873a3def", + "sha256:adb46ef41749db9bc55a6a1677ba4a43f0ae6a2c1a6cbfc056681d907cf1e3be", + "sha256:b8665e49b6cf7e40f969f0cb3ed87468cb14c64d845438185ff9c289c5f79381", + "sha256:bb9f3c2e9ab4a1fb28a7ad7e5012e133720656b606b8f560bc1bc55a8154e2d9", + "sha256:c02a304f5e8b147bca343e84b4de39629e2b761901c1fe99ecffa66c99875b80", + "sha256:c30904baf2de259979e0e13b99c605cd18c4523aa86170de5940edeb5dd348fa", + "sha256:c58a7d0a2365e28f065c68c0c958e1cc18f9c1dddbf9407842215eaf02f03011", + "sha256:c7b5bf2d05140db9609a8fa1716936e7e00d78d42e599167fc682d3b88dd05b9", + "sha256:c7c1502a042efb321da1556e94cc8ef6a035785b9ebcb5ddd4676b32e58d09f8", + "sha256:cacf78a5e3c5590bf281a1606a213ac5d6d9e0be71986449b7e523044abb2ea0", + "sha256:ce8c104cfc459cea32966f0ffbf189cbea379f69cff32aab33852d4a9cf0b532", + "sha256:d4b175792cd86c2ae2875f20f24e62f4ffe9d8ddea4c2e7ab1f0c43c9d8fc1e6", + "sha256:ea85757c9914a7f3b0ea1f8b1f9635afce1b96c89a043af5fc5778438a90fefc", + "sha256:ed274c0636c811800e0e2f834a616f1ee9ee6d14e21d3ae3e5281b77f9f66603", + "sha256:ee407148f57cedf49928a027b3d628d5fc005fec9da2af27eec34dc7b8da10da", + "sha256:f2959bb834090491a324938454aa424cc1ab3f80cadac6fd8e2133b179a638e4", + "sha256:f3c2d013bcb969b8a9b2e8aa9b6fcfaf9990d29eef496d1eee7d44a889b0f9b6", + "sha256:f780e496157ab1caeb6fe19079e4508c2d7a9f5489b298e04c40438a3ba0caf4", + "sha256:f9783247f4675a660f584c785ef44f637ddc0b2ee0112c6eacb3a8cec5be4021", + "sha256:fa8da902f2e29893e71394c6bf1d3ccb6df52d063d06982a3e8b4ec5118f1827" + ], + "index": "pypi", + "version": "==3.6.7" + }, + "certifi": { + "hashes": [ + "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", + "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7" + ], + "markers": "python_version >= '3.7'", + "version": "==2026.2.25" + }, + "charset-normalizer": { + "hashes": [ + "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc", + "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", + "sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67", + "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", + "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", + "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", + "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", + "sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444", + "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153", + "sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9", + "sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01", + "sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217", + "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", + "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", + "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", + "sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83", + "sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5", + "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", + "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", + "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", + "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", + "sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42", + "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", + "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", + "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", + "sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207", + "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", + "sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734", + "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", + "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", + "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", + "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", + "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", + "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", + "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", + "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", + "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", + "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53", + "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790", + "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", + "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", + "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", + "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", + "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", + "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", + "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", + "sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776", + "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", + "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", + "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008", + "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943", + "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374", + "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", + "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", + "sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5", + "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616", + "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", + "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", + "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", + "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752", + "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", + "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", + "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", + "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", + "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", + "sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4", + "sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545", + "sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706", + "sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366", + "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", + "sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a", + "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", + "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", + "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", + "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a", + "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", + "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", + "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", + "sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319", + "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", + "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", + "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", + "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", + "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", + "sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0", + "sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686", + "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34", + "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", + "sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c", + "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1", + "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", + "sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60", + "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", + "sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274", + "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", + "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", + "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", + "sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f", + "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d", + "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", + "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", + "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393", + "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", + "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af", + "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", + "sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00", + "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", + "sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3", + "sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7", + "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", + "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", + "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", + "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8", + "sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259", + "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", + "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", + "sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30", + "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", + "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", + "sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24", + "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", + "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", + "sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc", + "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", + "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", + "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", + "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", + "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", + "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464" + ], + "markers": "python_version >= '3.7'", + "version": "==3.4.7" + }, + "idna": { + "hashes": [ + "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", + "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" + ], + "markers": "python_version >= '3.8'", + "version": "==3.11" + }, + "numpy": { + "hashes": [ + "sha256:07077278157d02f65c43b1b26a3886bce886f95d20aabd11f87932750dfb14ed", + "sha256:08f2e31ed5e6f04b118e49821397f12767934cfdd12a1ce86a058f91e004ee50", + "sha256:0aec54fd785890ecca25a6003fd9a5aed47ad607bbac5cd64f836ad8666f4959", + "sha256:0d35aea54ad1d420c812bfa0385c71cd7cc5bcf7c65fed95fc2cd02fe8c79827", + "sha256:0d4e437e295f18ec29bc79daf55e8a47a9113df44d66f702f02a293d93a2d6dd", + "sha256:0dfd3f9d3adbe2920b68b5cd3d51444e13a10792ec7154cd0a2f6e74d4ab3233", + "sha256:1378871da56ca8943c2ba674530924bb8ca40cd228358a3b5f302ad60cf875fc", + "sha256:15716cfef24d3a9762e3acdf87e27f58dc823d1348f765bbea6bef8c639bfa1b", + "sha256:19710a9ca9992d7174e9c52f643d4272dcd1558c5f7af7f6f8190f633bd651a7", + "sha256:23cbfd4c17357c81021f21540da84ee282b9c8fba38a03b7b9d09ba6b951421e", + "sha256:2483e4584a1cb3092da4470b38866634bafb223cbcd551ee047633fd2584599a", + "sha256:27a8d92cd10f1382a67d7cf4db7ce18341b66438bdd9f691d7b0e48d104c2a9d", + "sha256:28a650663f7314afc3e6ec620f44f333c386aad9f6fc472030865dc0ebb26ee3", + "sha256:2aa0613a5177c264ff5921051a5719d20095ea586ca88cc802c5c218d1c67d3e", + "sha256:2c194dd721e54ecad9ad387c1d35e63dce5c4450c6dc7dd5611283dda239aabb", + "sha256:2d19e6e2095506d1736b7d80595e0f252d76b89f5e715c35e06e937679ea7d7a", + "sha256:2d390634c5182175533585cc89f3608a4682ccb173cc9bb940b2881c8d6f8fa0", + "sha256:30caa73029a225b2d40d9fae193e008e24b2026b7ee1a867b7ee8d96ca1a448e", + "sha256:42c16925aa5a02362f986765f9ebabf20de75cdefdca827d14315c568dcab113", + "sha256:45dbed2ab436a9e826e302fcdcbe9133f9b0006e5af7168afb8963a6520da103", + "sha256:4636de7fd195197b7535f231b5de9e4b36d2c440b6e566d2e4e4746e6af0ca93", + "sha256:4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af", + "sha256:4bbc7f303d125971f60ec0aaad5e12c62d0d2c925f0ab1273debd0e4ba37aba5", + "sha256:4d6d57903571f86180eb98f8f0c839fa9ebbfb031356d87f1361be91e433f5b7", + "sha256:4e874c976154687c1f71715b034739b45c7711bec81db01914770373d125e392", + "sha256:51fc224f7ca4d92656d5a5eb315f12eb5fe2c97a66249aa7b5f562528a3be38c", + "sha256:58c8b5929fcb8287cbd6f0a3fae19c6e03a5c48402ae792962ac465224a629a4", + "sha256:5a285b3b96f951841799528cd1f4f01cd70e7e0204b4abebac9463eecfcf2a40", + "sha256:5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf", + "sha256:62d6b0f03b694173f9fcb1fb317f7222fd0b0b103e784c6549f5e53a27718c44", + "sha256:6a246d5914aa1c820c9443ddcee9c02bec3e203b0c080349533fae17727dfd1b", + "sha256:6aa3236c78803afbcb255045fbef97a9e25a1f6c9888357d205ddc42f4d6eba5", + "sha256:6bbe4eb67390b0a0265a2c25458f6b90a409d5d069f1041e6aff1e27e3d9a79e", + "sha256:715d1c092715954784bc79e1174fc2a90093dc4dc84ea15eb14dad8abdcdeb74", + "sha256:72944b19f2324114e9dc86a159787333b77874143efcf89a5167ef83cfee8af0", + "sha256:81f4a14bee47aec54f883e0cad2d73986640c1590eb9bfaaba7ad17394481e6e", + "sha256:846300f379b5b12cc769334464656bc882e0735d27d9726568bc932fdc49d5ec", + "sha256:86b6f55f5a352b48d7fbfd2dbc3d5b780b2d79f4d3c121f33eb6efb22e9a2015", + "sha256:874f200b2a981c647340f841730fc3a2b54c9d940566a3c4149099591e2c4c3d", + "sha256:8a87ec22c87be071b6bdbd27920b129b94f2fc964358ce38f3822635a3e2e03d", + "sha256:8b3b60bb7cba2c8c81837661c488637eee696f59a877788a396d33150c35d842", + "sha256:8e3ed142f2728df44263aaf5fb1f5b0b99f4070c553a0d7f033be65338329150", + "sha256:93e15038125dc1e5345d9b5b68aa7f996ec33b98118d18c6ca0d0b7d6198b7e8", + "sha256:989824e9faf85f96ec9c7761cd8d29c531ad857bfa1daa930cba85baaecf1a9a", + "sha256:99d838547ace2c4aace6c4f76e879ddfe02bb58a80c1549928477862b7a6d6ed", + "sha256:9b2aec6af35c113b05695ebb5749a787acd63cafc83086a05771d1e1cd1e555f", + "sha256:9c585a1790d5436a5374bac930dad6ed244c046ed91b2b2a3634eb2971d21008", + "sha256:a7164afb23be6e37ad90b2f10426149fd75aee07ca55653d2aa41e66c4ef697e", + "sha256:ac6b31e35612a26483e20750126d30d0941f949426974cace8e6b5c58a3657b0", + "sha256:ad2e2ef14e0b04e544ea2fa0a36463f847f113d314aa02e5b402fdf910ef309e", + "sha256:b268594bccac7d7cf5844c7732e3f20c50921d94e36d7ec9b79e9857694b1b2f", + "sha256:b5f0362dc928a6ecd9db58868fca5e48485205e3855957bdedea308f8672ea4a", + "sha256:ba1f4fc670ed79f876f70082eff4f9583c15fb9a4b89d6188412de4d18ae2f40", + "sha256:ba203255017337d39f89bdd58417f03c4426f12beed0440cfd933cb15f8669c7", + "sha256:c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83", + "sha256:c9b39d38a9bd2ae1becd7eac1303d031c5c110ad31f2b319c6e7d98b135c934d", + "sha256:d2a8490669bfe99a233298348acc2d824d496dee0e66e31b66a6022c2ad74a5c", + "sha256:dddbbd259598d7240b18c9d87c56a9d2fb3b02fe266f49a7c101532e78c1d871", + "sha256:df3775294accfdd75f32c74ae39fcba920c9a378a2fc18a12b6820aa8c1fb502", + "sha256:e44319a2953c738205bf3354537979eaa3998ed673395b964c1176083dd46252", + "sha256:e4a010c27ff6f210ff4c6ef34394cd61470d01014439b192ec22552ee867f2a8", + "sha256:e823b8b6edc81e747526f70f71a9c0a07ac4e7ad13020aa736bb7c9d67196115", + "sha256:e892aff75639bbef0d2a2cfd55535510df26ff92f63c92cd84ef8d4ba5a5557f", + "sha256:eea7ac5d2dce4189771cedb559c738a71512768210dc4e4753b107a2048b3d0e", + "sha256:ef4059d6e5152fa1a39f888e344c73fdc926e1b2dd58c771d67b0acfbf2aa67d", + "sha256:f169b9a863d34f5d11b8698ead99febeaa17a13ca044961aa8e2662a6c7766a0", + "sha256:f2cf083b324a467e1ab358c105f6cad5ea950f50524668a80c486ff1db24e119", + "sha256:f8474c4241bc18b750be2abea9d7a9ec84f46ef861dbacf86a4f6e043401f79e", + "sha256:f983334aea213c99992053ede6168500e5f086ce74fbc4acc3f2b00f5762e9db", + "sha256:f9e75681b59ddaa5e659898085ae0eaea229d054f2ac0c7e563a62205a700121", + "sha256:fbc356aae7adf9e6336d336b9c8111d390a05df88f1805573ebb0807bd06fd1d", + "sha256:fcfe2045fd2e8f3cb0ce9d4ba6dba6333b8fa05bb8a4939c908cd43322d14c7e" + ], + "index": "pypi", + "markers": "python_version >= '3.11'", + "version": "==2.4.4" + }, + "pybind11": { + "hashes": [ + "sha256:432f01aeb68e361a3a7fc7575c2c7f497595bf640f747acd909ff238dd766e06", + "sha256:f8a6500548919cc33bcd220d5f984688326f574fa97f1107f2f4fdb4c6fb019f" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==3.0.2" + }, + "pygame": { + "hashes": [ + "sha256:00827aba089355925902d533f9c41e79a799641f03746c50a374dc5c3362e43d", + "sha256:10e3d2a55f001f6c0a6eb44aa79ea7607091c9352b946692acedb2ac1482f1c9", + "sha256:1206125f14cae22c44565c9d333607f1d9f59487b1f1432945dfc809aeaa3e88", + "sha256:14f9dda45469b254c0f15edaaeaa85d2cc072ff6a83584a265f5d684c7f7efd8", + "sha256:15efaa11a80a65dd589a95bebe812fa5bfc7e14946b638a424c5bd9ac6cca1a4", + "sha256:163e66de169bd5670c86e27d0b74aad0d2d745e3b63cf4e7eb5b2bff1231ca8d", + "sha256:173badf82fa198e6888017bea40f511cb28e69ecdd5a72b214e81e4dcd66c3b1", + "sha256:17498a2b043bc0e795faedef1b081199c688890200aef34991c1941caa2d2c89", + "sha256:20349195326a5e82a16e351ed93465a7845a7e2a9af55b7bc1b2110ea3e344e1", + "sha256:21160d9093533eb831f1b708e630706e5ac16b30750571ec27bc3b8364814f38", + "sha256:27eb17e3dc9640e4b4683074f1890e2e879827447770470c2aba9f125f74510b", + "sha256:28b43190436037e428a5be28fc80cf6615304fd528009f2c688cc828f4ff104b", + "sha256:2a3a1288e2e9b1e5834e425bedd5ba01a3cd4902b5c2bff8ed4a740ccfe98171", + "sha256:2a615d78b2364e86f541458ff41c2a46181b9a1e9eabd97b389282fdf04efbb3", + "sha256:325a84d072d52e3c2921eff02f87c6a74b7e77d71db3bdf53801c6c975f1b6c4", + "sha256:33006f784e1c7d7e466fcb61d5489da59cc5f7eb098712f792a225df1d4e229d", + "sha256:3a9e7396be0d9633831c3f8d5d82dd63ba373ad65599628294b7a4f8a5a01a65", + "sha256:3acd8c009317190c2bfd81db681ecef47d5eb108c2151d09596d9c7ea9df5c0e", + "sha256:3bede70ec708057e305815d6546012669226d1d80566785feca9b044216062e7", + "sha256:481cfe1bdbb7fe00acc5950c494c26f00240888619bdc396fc8c39a734797432", + "sha256:4a8ea113b1bf627322a025a1a5a87e3818a7f55ab3a4077ff1ae5c8c60576614", + "sha256:4c1623180e70a03c4a734deb9bac50fc9c82942ae84a3a220779062128e75f3b", + "sha256:4ee7f2771f588c966fa2fa8b829be26698c9b4836f82ede5e4edc1a68594942e", + "sha256:56fb02ead529cee00d415c3e007f75e0780c655909aaa8e8bf616ee09c9feb1f", + "sha256:56ffca6059b165bbf64f4b4be23b8068f6a0e220780e4f96ec0bb5ac3c63ec39", + "sha256:5d09fd950725d187aa5207c0cb8eb9ab0d2f8ce9ab8d189c30eeb470e71b617e", + "sha256:6582aa71a681e02e55d43150a9ab41394e6bf4d783d2962a10aea58f424be060", + "sha256:7103c60939bbc1e05cfc7ba3f1d2ad3bbf103b7828b82a7166a9ab6f51950146", + "sha256:7bffdd3eaf394d9645331d1c3a5df9d782ebcc3c5a78f3b657c7879a828dd111", + "sha256:811e7b925146d8149d79193652cbb83e0eca0aae66476b1cb310f0f4226b8b5c", + "sha256:813af4fba5d0b2cb8e58f5d95f7910295c34067dcc290d34f1be59c48bd1ea6a", + "sha256:816e85000c5d8b02a42b9834f761a5925ef3377d2924e3a7c4c143d2990ce5b8", + "sha256:818b4eaec9c4acb6ac64805d4ca8edd4062bebca77bd815c18739fe2842c97e9", + "sha256:84fc4054e25262140d09d39e094f6880d730199710829902f0d8ceae0213379e", + "sha256:8a78fd030d98faab4a8e27878536fdff7518d3e062a72761c552f624ebba5a5f", + "sha256:91476902426facd4bb0dad4dc3b2573bc82c95c71b135e0daaea072ed528d299", + "sha256:94afd1177680d92f9214c54966ad3517d18210c4fbc5d84a0192d218e93647e0", + "sha256:97ac4e13847b6b293ecaffa5ffce9886c98d09c03309406931cc592f0cea6366", + "sha256:9beeb647e555afb5657111fa83acb74b99ad88761108eaea66472e8b8547b55b", + "sha256:9dd5c054d4bd875a8caf978b82672f02bec332f52a833a76899220c460bb4b58", + "sha256:a1bf7ab5311bbced70320f1a56701650b4c18231343ae5af42111eea91e0949a", + "sha256:a4b8f04fceddd9a3ac30778d11f0254f59efcd1c382d5801271113cea8b4f2f3", + "sha256:a620883d589926f157b8f1d1f543183ac52e5c30507dea445e3927ae0bee1c54", + "sha256:ac3f033d2be4a9e23660a96afe2986df3a6916227538a6a0061bc218c5088507", + "sha256:ae6039f3a55d800db80e8010f387557b528d34d534435e0871326804df2a62f2", + "sha256:b46e68cd168f44d0224c670bb72186688fc692d7079715f79d04096757d703d0", + "sha256:b7f9f8e6f76de36f4725175d686601214af362a4f30614b4dae2240198e72e6f", + "sha256:bbb7167c92103a2091366e9af26d4914ba3776666e8677d3c93551353fffa626", + "sha256:c0b11356ac96261162d54a2c2b41a41978f00525631b01ec9c4fe26b01c66595", + "sha256:c31dbdb5d0217f32764797d21c2752e258e5fb7e895326538d82b5f75a0cd856", + "sha256:c47a6938de93fa610accd4969e638c2aebcb29b2fca518a84c3a39d91ab47116", + "sha256:c8040ea2ab18c6b255af706ec01355c8a6b08dc48d77fd4ee783f8fc46a843bf", + "sha256:ce8cc108b92de9b149b344ad2e25eedbe773af0dc41dfb24d1f07f679b558c60", + "sha256:d1a7f2b66ac2e4c9583b6d4c6d6f346fb10a3392c04163f537061f86a448ed5c", + "sha256:d29eb9a93f12aa3d997b6e3c447ac85b2a4b142ab2548441523a8fcf5e216042", + "sha256:da3ad64d685f84a34ebe5daacb39fff14f1251acb34c098d760d63fee768f50c", + "sha256:ef07c0103d79492c21fced9ad68c11c32efa6801ca1920ebfd0f15fb46c78b1c", + "sha256:f3935459109da4bb0b3901da9904f0a3e52028a3332a355d298b1673a334cf21", + "sha256:f84f15d146d6aa93254008a626c56ef96fed276006202881a47b29757f0cd65a", + "sha256:fb6e8d0547f30ddc845f4fd1e33070ef548233ad0dbf21f7ecea768883d1bbdc" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==2.6.1" + }, + "requests": { + "hashes": [ + "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", + "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==2.33.1" + }, + "scipy": { + "hashes": [ + "sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0", + "sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458", + "sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118", + "sha256:131f5aaea57602008f9822e2115029b55d4b5f7c070287699fe45c661d051e39", + "sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e", + "sha256:1cc682cea2ae55524432f3cdff9e9a3be743d52a7443d0cba9017c23c87ae2f6", + "sha256:1f95b894f13729334fb990162e911c9e5dc1ab390c58aa6cbecb389c5b5e28ec", + "sha256:200e1050faffacc162be6a486a984a0497866ec54149a01270adc8a59b7c7d21", + "sha256:2040ad4d1795a0ae89bfc7e8429677f365d45aa9fd5e4587cf1ea737f927b4a1", + "sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6", + "sha256:2ceb2d3e01c5f1d83c4189737a42d9cb2fc38a6eeed225e7515eef71ad301dce", + "sha256:35c3a56d2ef83efc372eaec584314bd0ef2e2f0d2adb21c55e6ad5b344c0dcb8", + "sha256:37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448", + "sha256:3877ac408e14da24a6196de0ddcace62092bfc12a83823e92e49e40747e52c19", + "sha256:3fd1fcdab3ea951b610dc4cef356d416d5802991e7e32b5254828d342f7b7e0b", + "sha256:41b71f4a3a4cab9d366cd9065b288efc4d4f3c0b37a91a8e0947fb5bd7f31d87", + "sha256:43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4", + "sha256:45abad819184f07240d8a696117a7aacd39787af9e0b719d00285549ed19a1e9", + "sha256:4b400bdc6f79fa02a4d86640310dde87a21fba0c979efff5248908c6f15fad1b", + "sha256:4eb6c25dd62ee8d5edf68a8e1c171dd71c292fdae95d8aeb3dd7d7de4c364082", + "sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464", + "sha256:5cf36e801231b6a2059bf354720274b7558746f3b1a4efb43fcf557ccd484a87", + "sha256:5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c", + "sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369", + "sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad", + "sha256:6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f", + "sha256:744b2bf3640d907b79f3fd7874efe432d1cf171ee721243e350f55234b4cec4c", + "sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475", + "sha256:766e0dc5a616d026a3a1cffa379af959671729083882f50307e18175797b3dfd", + "sha256:7bdf2da170b67fdf10bca777614b1c7d96ae3ca5794fd9587dce41eb2966e866", + "sha256:7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d", + "sha256:844e165636711ef41f80b4103ed234181646b98a53c8f05da12ca5ca289134f6", + "sha256:8a604bae87c6195d8b1045eddece0514d041604b14f2727bbc2b3020172045eb", + "sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca", + "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", + "sha256:9cdc1a2fcfd5c52cfb3045feb399f7b3ce822abdde3a193a6b9a60b3cb5854ca", + "sha256:9ecb4efb1cd6e8c4afea0daa91a87fbddbce1b99d2895d151596716c0b2e859d", + "sha256:a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee", + "sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4", + "sha256:a48a72c77a310327f6a3a920092fa2b8fd03d7deaa60f093038f22d98e096717", + "sha256:a720477885a9d2411f94a93d16f9d89bad0f28ca23c3f8daa521e2dcc3f44d49", + "sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2", + "sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a", + "sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350", + "sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950", + "sha256:c80be5ede8f3f8eded4eff73cc99a25c388ce98e555b17d31da05287015ffa5b", + "sha256:cc90d2e9c7e5c7f1a482c9875007c095c3194b1cfedca3c2f3291cdc2bc7c086", + "sha256:cd96a1898c0a47be4520327e01f874acfd61fb48a9420f8aa9f6483412ffa444", + "sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068", + "sha256:d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff", + "sha256:d59c30000a16d8edc7e64152e30220bfbd724c9bbb08368c054e24c651314f0a", + "sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50", + "sha256:e18f12c6b0bc5a592ed23d3f7b891f68fd7f8241d69b7883769eb5d5dfb52696", + "sha256:e19ebea31758fac5893a2ac360fedd00116cbb7628e650842a6691ba7ca28a21", + "sha256:e30bdeaa5deed6bc27b4cc490823cd0347d7dae09119b8803ae576ea0ce52e4c", + "sha256:eb092099205ef62cd1782b006658db09e2fed75bffcae7cc0d44052d8aa0f484", + "sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118", + "sha256:f4115102802df98b2b0db3cce5cb9b92572633a1197c77b7553e5203f284a5b3", + "sha256:f590cd684941912d10becc07325a3eeb77886fe981415660d9265c4c418d0bea", + "sha256:f8885db0bc2bffa59d5c1b72fad7a6a92d3e80e7257f967dd81abb553a90d293", + "sha256:fcb310ddb270a06114bb64bbe53c94926b943f5b7f0842194d585c65eb4edd76" + ], + "index": "pypi", + "markers": "python_version >= '3.11'", + "version": "==1.17.1" + }, + "setuptools": { + "hashes": [ + "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", + "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==82.0.1" + }, + "urllib3": { + "hashes": [ + "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", + "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4" + ], + "markers": "python_version >= '3.9'", + "version": "==2.6.3" + } + }, + "develop": {} +} diff --git a/auto_sim/README.md b/auto_sim/README.md new file mode 100644 index 0000000..4397b68 --- /dev/null +++ b/auto_sim/README.md @@ -0,0 +1,6 @@ +# TODO + +* basic boundary checking, triangulation +* basic controller? +* full MPC + diff --git a/auto_sim/constants.py b/auto_sim/constants.py new file mode 100644 index 0000000..06c3380 --- /dev/null +++ b/auto_sim/constants.py @@ -0,0 +1 @@ +VEHICLE_WIDTH_M = 1.2 \ No newline at end of file diff --git a/auto_sim/fsae.png b/auto_sim/fsae.png new file mode 100644 index 0000000..2e94f53 Binary files /dev/null and b/auto_sim/fsae.png differ diff --git a/auto_sim/main.py b/auto_sim/main.py new file mode 100644 index 0000000..bb1faaf --- /dev/null +++ b/auto_sim/main.py @@ -0,0 +1,77 @@ +import pygame +from Controller import compute, sim_step, Cone, ConeColor, VehicleState, mock_perception, compute_path +from render import init, render_world +import ctypes +import platform + +# dpi awareness for windows - prevents blurry rendering on high dpi displays +if platform.system() == "Windows": + try: + # Set DPI Awareness (Windows 10/8) + ctypes.windll.shcore.SetProcessDpiAwareness(2) + except AttributeError: + # Windows 7/Vista + ctypes.windll.user32.SetProcessDPIAware() + +CONE_POSITIONS: list[Cone] = [] +with open("labels/0000001.txt", "r") as f: + lines = f.readlines() + for line in lines: + x, y, _, _, _, _, _, color = line.strip().split() + cone_color = ConeColor.YELLOW if color == "Cone_Yellow" else ConeColor.BLUE + CONE_POSITIONS.append(Cone(float(x), float(y), cone_color)) + +# pygame setup +pygame.init() +screen = pygame.display.set_mode((1900, 1200), pygame.RESIZABLE) +pygame.display.set_caption('Autonomous Sim') +clock = pygame.time.Clock() +running = True +time: float = 0.0 +init() + +vehicle_state: VehicleState = VehicleState() +# vehicle_state.v_y = 2.0 +# vehicle_state.theta = math.radians(23.54) +# vehicle_state.omega = -0.2 + +def handle_key(key: int, state: VehicleState): + match key: + case pygame.K_d: state.y -= 1 + case pygame.K_a: state.y += 1 + case pygame.K_w: state.x += 1 + case pygame.K_s: state.x -= 1 + +ran = False +def simulate_cone_detection(state: VehicleState): + global ran + if not ran: + mock_perception(CONE_POSITIONS) + compute_path() + ran = True + return CONE_POSITIONS + +while running: + # handle events + # pygame.QUIT event means the user clicked X to close your window + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + elif event.type == pygame.KEYDOWN: + handle_key(event.key, vehicle_state) + + # this is what is running on the + detected_cones = simulate_cone_detection(vehicle_state) + controls = compute(vehicle_state) + + # closing the SIL loop + dt = clock.get_time() + screen.fill("black") + sim_step(vehicle_state, controls, dt) + render_world(vehicle_state, CONE_POSITIONS, screen) + + # flip() the display to put your work on screen + pygame.display.flip() + clock.tick(60) # limits FPS to 60 + +pygame.quit() \ No newline at end of file diff --git a/auto_sim/render.py b/auto_sim/render.py new file mode 100644 index 0000000..9f366ee --- /dev/null +++ b/auto_sim/render.py @@ -0,0 +1,175 @@ +from typing import Tuple + +import pygame +from scipy.spatial.transform import Rotation as R +from constants import VEHICLE_WIDTH_M +from Controller import VehicleState, Cone, ConeColor, spline_t, project, get_center_line_length, get_center_points +from math import ceil, degrees +import numpy as np +from colorsys import hsv_to_rgb + +PIXELS_PER_M = 20.0 +w: int +h: int + +car: pygame.Surface +vignette: pygame.Surface + +def init(): + global car, vignette + car = pygame.image.load('fsae.png').convert_alpha() + vignette_image = pygame.image.load('vignette.png').convert_alpha() + vignette_image = pygame.transform.scale(vignette_image, (30 * PIXELS_PER_M,30 * PIXELS_PER_M)) + vignette = pygame.Surface((3000,3000), pygame.SRCALPHA) + vignette.blit(vignette_image, vignette_image.get_rect(center=(1500,1500))) + +def transform(x: float, y: float, vehicle_state: VehicleState) -> tuple[int, int]: + """ + Transforms from global coordinates to screen space coordinates + """ + global w, h + r = R.from_euler('z', -vehicle_state.theta + np.pi/2, degrees=False) + rel_x, rel_y = x - vehicle_state.x, y - vehicle_state.y + rotated_x, rotated_y,_ = r.apply([rel_x, rel_y, 0]) + screen_x = int(w / 2 + rotated_x * PIXELS_PER_M) + screen_y = int((h * 0.67) - rotated_y * PIXELS_PER_M) + # Simple transformation - replace with actual coordinate transformation logic + return (screen_x, screen_y) + +def create_grid_surface(l: int, spacing_px: int, color: str) -> pygame.Surface: + grid_surf = pygame.Surface((2*l,2*l), pygame.SRCALPHA) + for x in range(0, 2*l, spacing_px): + pygame.draw.line(grid_surf, color, (x, 0), (x, 2*l), 2) + for y in range(0, 2*l, spacing_px): + pygame.draw.line(grid_surf, color, (0, y), (2*l, y), 2) + return grid_surf + +old_state = None, None, None +old_grid_surf = None +def drawGrid(screen: pygame.Surface, state: VehicleState, color=(45, 45, 45), spacing_m=1): + global h, w, old_state, old_grid_surf, vignette + # create grid, cached + spacing_px = int(spacing_m * PIXELS_PER_M) + l: int= ceil(np.hypot(w/2, h/2) * 0.4 / spacing_m) * spacing_m + if (spacing_m, color, l) != old_state or old_grid_surf is None: + print("RERENDERING GRID") + old_state = (spacing_m, color, l) + old_grid_surf = create_grid_surface(2*l, spacing_px, color) + grid_surf = old_grid_surf + + # grid + screen_grid = pygame.surface.Surface((w, h), pygame.SRCALPHA) + + # Calculate grid offset to align with world coordinates + r = R.from_euler('z', -state.theta + np.pi/2, degrees=False) + x, y = r.apply([state.x % spacing_m, state.y % spacing_m, 0])[:2] + rotated_surf: pygame.Surface = pygame.transform.rotate(grid_surf, degrees(-state.theta - np.pi/2)) + screen_grid.blit(rotated_surf, rotated_surf.get_rect(center=( + w/2 - x * PIXELS_PER_M, + 0.67 * h + y * PIXELS_PER_M + )).topleft) + + # vignette + screen_grid.blit(vignette, vignette.get_rect(center=(w/2, 0.67*h)), special_flags=pygame.BLEND_RGBA_MULT) + + screen.blit(screen_grid, (0, 0)) + + +# def create_spline_surface(): +# surf = pygame.Surface((77 * PIXELS_PER_M, 47 * PIXELS_PER_M), pygame.SRCALPHA) +# length = get_center_line_length() +# for x in range(int(77 * PIXELS_PER_M)): +# for y in range(int(47 * PIXELS_PER_M)): +# k = hsv_to_rgb(project(22-x/PIXELS_PER_M, -39+y/PIXELS_PER_M)/length, 1, 1) +# surf.set_at((x, y), (int(k[0]*255), int(k[1]*255), int(k[2]*255))) +# return surf + +# spline_surface = None +# def drawSplintSurface(screen: pygame.Surface, vehicle_state: VehicleState): +# global spline_surface +# if spline_surface is None: +# spline_surface = create_spline_surface() +# rotated_surf: pygame.Surface = pygame.transform.rotate(spline_surface, degrees(-vehicle_state.theta - np.pi/2)) +# screen.blit(rotated_surf, rotated_surf.get_rect(center=transform(-16.5, -15.5, vehicle_state))) + + +def int_to_color(value: ConeColor) -> str: + match value: + case ConeColor.BLUE: + return "blue" + case ConeColor.YELLOW: + return "yellow" + case _: + return "white" + +at_t = None +def render_world(vehicle_state: VehicleState, cones: list[Cone], screen: pygame.Surface): + global w, h, at_t + w, h = screen.get_width(), screen.get_height() + + # grid for context + drawGrid(screen, vehicle_state) + # drawSplintSurface(screen, vehicle_state) + + # pygame.draw.circle(screen, "white", transform(0, 0, vehicle_state), 5) + + # DRAW TRIANGULATION + # for edge in get_offline_edges(): + # v1, v2 = cones[edge.v1()], cones[edge.v2()] + # default_colour = "#676767" + # pygame.draw.line(screen, default_colour, + # transform(v1.x, v1.y, vehicle_state), + # transform(v2.x, v2.y, vehicle_state), 2 + # ) + # for edge in get_boundary_edges(): + # v1, v2 = cones[edge.v1()], cones[edge.v2()] + # default_colour = "#FF0000" + # if v1.c == v2.c: + # match v1.c: + # case ConeColor.BLUE: + # default_colour = "blue" + # case ConeColor.YELLOW: + # default_colour = "yellow" + # pygame.draw.line(screen, default_colour, + # transform(v1.x, v1.y, vehicle_state), + # transform(v2.x, v2.y, vehicle_state), 1 + # ) + + # DRAW CENTER LINE + # center_points = get_center_points() + # for i in range(len(center_points)): + # v1, v2 = center_points[i], center_points[(i+1) % len(center_points)] # returns cone objects + # default_colour = "#676767" + # pygame.draw.line(screen, default_colour, + # transform(v1.x, v1.y, vehicle_state), + # transform(v2.x, v2.y, vehicle_state), 2 + # ) + + # DRAW PATH PROJECTION + # at_t = project(vehicle_state.x, vehicle_state.y) + # x = spline_t(at_t) + # pygame.draw.circle(screen, "red", transform(x.x, x.y, vehicle_state), 5) + + # DRAW SPLINE + # steps = 100 + # dt = get_center_line_length() / steps + # for t in range(steps): + # x1 = spline_t(t * dt) + # x2= spline_t((t + 1) * dt) + # pygame.draw.line(screen, "#676767", + # transform(x1.x, x1.y, vehicle_state), + # transform(x2.x, x2.y, vehicle_state), 2) + + for cone in cones: + pygame.draw.circle( + screen, int_to_color(cone.c), + transform(cone.x, cone.y, vehicle_state), 0.2 * PIXELS_PER_M + ) + + car_rotated = pygame.transform.rotate(car,-90) + scale_factor = VEHICLE_WIDTH_M / car_rotated.get_width() * PIXELS_PER_M + car_scaled = pygame.transform.scale(car_rotated, ( + car_rotated.get_width() * scale_factor, car_rotated.get_height() * scale_factor + )) + car_rect = car_scaled.get_rect(center=transform(vehicle_state.x, vehicle_state.y, vehicle_state)) + screen.blit(car_scaled, car_rect) \ No newline at end of file diff --git a/auto_sim/test_controller_2/.clang-format b/auto_sim/test_controller_2/.clang-format new file mode 100644 index 0000000..8b0cf95 --- /dev/null +++ b/auto_sim/test_controller_2/.clang-format @@ -0,0 +1,3 @@ +BasedOnStyle: WebKit +BreakBeforeBraces: Attach +PackConstructorInitializers: NextLine diff --git a/auto_sim/test_controller_2/CMakeLists.txt b/auto_sim/test_controller_2/CMakeLists.txt new file mode 100644 index 0000000..104c72a --- /dev/null +++ b/auto_sim/test_controller_2/CMakeLists.txt @@ -0,0 +1,53 @@ +cmake_minimum_required(VERSION 3.10) +set(CMAKE_CXX_STANDARD 23) +project(high_level_controller) + +file( + DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.40.8/CPM.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake + EXPECTED_HASH SHA256=78ba32abdf798bc616bab7c73aac32a17bbd7b06ad9e26a6add69de8f3ae4791 +) +include(${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake) + +CPMAddPackage( + NAME pybind11 + GIT_REPOSITORY https://github.com/pybind/pybind11.git + VERSION 3.0.2 + DOWNLOAD_ONLY TRUE +) +add_subdirectory(${pybind11_SOURCE_DIR}) + +CPMAddPackage( + NAME CDT + GIT_REPOSITORY https://github.com/artem-ogre/CDT.git + GIT_TAG 1.4.4 + DOWNLOAD_ONLY TRUE +) +CPMAddPackage( + NAME EIGEN + GIT_REPOSITORY https://gitlab.com/libeigen/eigen + GIT_TAG 3147391d946bb4b6c68edd901f2add6ac1f31f8c + GIT_SHALLOW TRUE + DOWNLOAD_ONLY TRUE +) +set(EIGEN_INCLUDE_DIRS ${EIGEN_SOURCE_DIR}) +add_library(eigen_interface INTERFACE) +target_include_directories(eigen_interface SYSTEM INTERFACE ${EIGEN_INCLUDE_DIRS}) +target_compile_definitions(eigen_interface INTERFACE + EIGEN_STACK_ALLOCATION_LIMIT=0 + EIGEN_MAX_STATIC_ALIGN_BYTES=0 +) + +CPMAddPackage( + NAME alglib + URL https://www.alglib.net/translator/re/alglib-4.07.0.cpp.gpl.zip + DOWNLOAD_ONLY TRUE +) +add_library(alglib_interface INTERFACE) +target_include_directories(alglib_interface INTERFACE ${alglib_SOURCE_DIR}/src) + +file(GLOB SOURCES *.cpp ${alglib_SOURCE_DIR}/src/*.cpp) +pybind11_add_module(controller ${SOURCES}) +target_include_directories(controller PRIVATE ${CDT_SOURCE_DIR}/CDT/include) +target_link_libraries(controller PRIVATE eigen_interface alglib_interface) \ No newline at end of file diff --git a/auto_sim/test_controller_2/CMakePresets.json b/auto_sim/test_controller_2/CMakePresets.json new file mode 100644 index 0000000..3276da1 --- /dev/null +++ b/auto_sim/test_controller_2/CMakePresets.json @@ -0,0 +1,19 @@ +{ + "version": 10, + "configurePresets": [ + { + "name": "default_win", + "generator": "Visual Studio 17 2022", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + } + }, + { + "name": "default_unix", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + } + } + ] +} \ No newline at end of file diff --git a/auto_sim/test_controller_2/README.md b/auto_sim/test_controller_2/README.md new file mode 100644 index 0000000..9a603c5 --- /dev/null +++ b/auto_sim/test_controller_2/README.md @@ -0,0 +1,9 @@ +# Development +To develop, set up as per usual as a CMake project. + +# Installation +```bash +pip install ./test_controller_2 +``` + +This will trigger setup.py which will automatically install the python package into the environment of your choosing \ No newline at end of file diff --git a/auto_sim/test_controller_2/controller.cpp b/auto_sim/test_controller_2/controller.cpp new file mode 100644 index 0000000..2c6caa3 --- /dev/null +++ b/auto_sim/test_controller_2/controller.cpp @@ -0,0 +1,6 @@ +#include "controller.hpp" + +ControlOutput compute(const VehicleState& ve) { + // t.adj will contain the adj list + return { 0, 0 }; +} \ No newline at end of file diff --git a/auto_sim/test_controller_2/controller.hpp b/auto_sim/test_controller_2/controller.hpp new file mode 100644 index 0000000..cdf4921 --- /dev/null +++ b/auto_sim/test_controller_2/controller.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "types.hpp" + +ControlOutput compute(const VehicleState& ve); + +enum class DriverlessState { + IDLE, + ONLINE_MAPPING, // use for autocross, acceleration, skidpad, etc. + TRACKDRIVE_MAPPING, + TRACKDRIVE_RUNNING +}; \ No newline at end of file diff --git a/auto_sim/test_controller_2/path.cpp b/auto_sim/test_controller_2/path.cpp new file mode 100644 index 0000000..6c39b83 --- /dev/null +++ b/auto_sim/test_controller_2/path.cpp @@ -0,0 +1,170 @@ +#include "path.hpp" +#include "perception.hpp" +#include "scopetimer.hpp" +#include + +static std::vector calculate_boundary(const std::vector& cones, const ConeColor c) { + size_t start = 0; + std::unordered_set unvisited_cones { }; + for (size_t i = 0; i < cones.size(); ++i) { + if (cones[i].c == c) { + start = i; + unvisited_cones.insert(i); + } + } + size_t at = start; + + std::vector path; + path.reserve(unvisited_cones.size()); + path.push_back(at); + unvisited_cones.erase(at); + while (not unvisited_cones.empty()) { + // find cone with shortest distance to cones[at] + size_t closest_cone = 0; + double closest_dist = std::numeric_limits::max(); + for (const size_t i : unvisited_cones) { + if (const double dist = std::hypot(cones[at].x - cones[i].x, cones[at].y - cones[i].y); dist < closest_dist) { + closest_dist = dist; + closest_cone = i; + } + } + if (closest_cone == start) { + break; + } + unvisited_cones.erase(closest_cone); + path.push_back(closest_cone); + at = closest_cone; + } + + return path; +} + +static double mod(const double a, const double b) { + const double result = std::fmod(a, b); + return result >= 0 ? result : result + b; +} + +void compute_path_from_percepted_cones() { + ScopeTimer s { "compute_path timer" }; + static CDT::Triangulation cdt_cache; + static size_t seen_cones = 0; + if (seen_cones == cones.size()) { + return; + } + const auto start = std::next(cones.begin(), static_cast::difference_type>(seen_cones)); + cdt_cache.insertVertices( + start, cones.end(), [](const Cone& c) { return c.x; }, [](const Cone& c) { return c.y; }); + + // calculate boundary edges and insert them into the triangulation + std::vector edges { }; + const std::vector blue_boundary = calculate_boundary(cones, ConeColor::BLUE); + for (size_t i = 0; i < blue_boundary.size(); ++i) { + edges.emplace_back(blue_boundary[i], blue_boundary[(i + 1) % blue_boundary.size()]); + } + const std::vector yellow_boundary = calculate_boundary(cones, ConeColor::YELLOW); + for (size_t i = 0; i < yellow_boundary.size(); ++i) { + edges.emplace_back(yellow_boundary[i], yellow_boundary[(i + 1) % yellow_boundary.size()]); + } + // compute corresponding triangulation + CDT::Triangulation cdt = cdt_cache; + cdt.insertEdges(edges); + cdt.eraseOuterTrianglesAndHoles(); + offline_boundary_edges = cdt.fixedEdges; + offline_inner_edges = CDT::extractEdgesFromTriangles(cdt.triangles); + const size_t original_num_edges = offline_inner_edges.size(); + for (const auto e : offline_boundary_edges) { + offline_inner_edges.erase(e); + } + assert(offline_inner_edges.size() + offline_boundary_edges.size() == original_num_edges); + + // construct center line + std::vector _centers = { }; + for (const auto e : offline_inner_edges) { + // get center point of e + const Cone& c1 = cones[e.v1()]; + const Cone& c2 = cones[e.v2()]; + _centers.emplace_back((c1.x + c2.x) / 2, (c1.y + c2.y) / 2, ConeColor::CENTER); + } + const std::vector _center_idxs = calculate_boundary(_centers, ConeColor::CENTER); + center_points.clear(); + center_points.reserve(_center_idxs.size()); + for (const size_t i : _center_idxs) { + center_points.push_back(_centers[i]); + } + + // center line parameterization prefix + alglib::real_1d_array center_line_len_prefix; + center_line_len_prefix.setlength(center_points.size() + 1); + center_line_len_prefix[0] = 0; + for (size_t i = 1; i <= center_points.size(); ++i) { + const Cone& c1 = center_points[i - 1]; + const Cone& c2 = center_points[i % center_points.size()]; + center_line_len_prefix[i] = center_line_len_prefix[i - 1] + std::hypot(c1.x - c2.x, c1.y - c2.y); + } + center_line_length = center_line_len_prefix[center_points.size()]; + + // draw a spline between all the center points + alglib::real_1d_array xs, ys; + xs.setlength(center_points.size() + 1); + ys.setlength(center_points.size() + 1); + for (size_t i = 0; i < center_points.size(); ++i) { + const Cone& c = center_points[i]; + xs[i] = c.x; + ys[i] = c.y; + } + // cycle around + xs[center_points.size()] = center_points[0].x; + ys[center_points.size()] = center_points[0].y; + + alglib::spline1dbuildcubic(center_line_len_prefix, xs, x_spline); + alglib::spline1dbuildcubic(center_line_len_prefix, ys, y_spline); +} + +double project(const double x, const double y) { + // const ScopeTimer s { "project timer" }; + static constexpr uint32_t samples = 50; + static constexpr double eps = 0; + + double best_dist = std::numeric_limits::max(), best_t = 0; + const double step_size = center_line_length / samples - eps; + assert(step_size > 0); + for (double at_t = eps; at_t < center_line_length; at_t += step_size) { // NOLINT(*-flp30-c) + const double t = project(x, y, at_t); + const double d = std::hypot( + alglib::spline1dcalc(x_spline, t) - x, + alglib::spline1dcalc(y_spline, t) - y); + if (d < best_dist) { + best_dist = d; + best_t = t; + } + } + return best_t; +} +double project(const double x0, const double y0, double t) { + // just good to double check + assert(0 <= t); + assert(t <= center_line_length); + + // newton stepping ???? + for (uint32_t i = 0; i < 20; i++) { + double l_x, l_dx, l_ddx; + alglib::spline1ddiff(x_spline, t, l_x, l_dx, l_ddx); + double l_y, l_dy, l_ddy; + alglib::spline1ddiff(y_spline, t, l_y, l_dy, l_ddy); + // ||l'(t)||_2 + (l(t) - x) dot l''(t) + const double f_prime = (l_dx * l_dx + l_dy * l_dy) + ((l_x - x0) * l_ddx + (l_y - y0) * l_ddy); + // (l(t) - x) dot l'(t) + const double f = (l_x - x0) * l_dx + (l_y - y0) * l_dy; + const double step = f / f_prime; + t = mod(t - step, center_line_length); + if (step < 1e-6) { + return t; + } + } + std::cout << "project did not converge at x=" << x0 << "and y=" << y0 << std::endl; + throw std::exception("project did not converge"); +} + +Location spline_t(const double t) { + return { alglib::spline1dcalc(x_spline, t), alglib::spline1dcalc(y_spline, t) }; +} diff --git a/auto_sim/test_controller_2/path.hpp b/auto_sim/test_controller_2/path.hpp new file mode 100644 index 0000000..466c2d0 --- /dev/null +++ b/auto_sim/test_controller_2/path.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include "CDT.h" +#include "interpolation.h" +#include "types.hpp" + +#include + +/** + * This computes the path from the given ALL cones offline. + */ +void compute_path_from_percepted_cones(); +/** + * Note this overload is MUCH faster than without at_t + * @param x0 x position + * @param y0 y position + * @param t please use this to seed the optimization algorithm + * @return t s.t. the point on the center line that is closest to (x, y) in terms of Euclidean distance + */ +double project(double x0, double y0, double t); +/** + * this variant tries a bunch of values of at_t, between [0, center_line_length], and returns the best one. + * this is more expensive but can be more robust if the center line is very curvy and the optimization algorithm gets stuck in a local minimum. + * @param x x position + * @param y y position + * @return + */ +double project(double x, double y); + +struct Location { + double x; + double y; +}; +Location spline_t(double t); + +// for debugging purposes only +inline CDT::EdgeUSet offline_boundary_edges; +inline CDT::EdgeUSet offline_inner_edges; +inline std::vector center_points; +// inline std::vector center_line_idxs; +inline alglib::spline1dinterpolant x_spline, y_spline; +inline double center_line_length; \ No newline at end of file diff --git a/auto_sim/test_controller_2/perception.cpp b/auto_sim/test_controller_2/perception.cpp new file mode 100644 index 0000000..f90e7de --- /dev/null +++ b/auto_sim/test_controller_2/perception.cpp @@ -0,0 +1 @@ +#include "perception.hpp" diff --git a/auto_sim/test_controller_2/perception.hpp b/auto_sim/test_controller_2/perception.hpp new file mode 100644 index 0000000..377c27c --- /dev/null +++ b/auto_sim/test_controller_2/perception.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "types.hpp" +#include + +inline std::vector cones { }; +inline void mock_perception(std::vector new_cones) { + cones = std::move(new_cones); +} \ No newline at end of file diff --git a/auto_sim/test_controller_2/pybind.cpp b/auto_sim/test_controller_2/pybind.cpp new file mode 100644 index 0000000..8c2c864 --- /dev/null +++ b/auto_sim/test_controller_2/pybind.cpp @@ -0,0 +1,111 @@ +#include +#include + +#include "CDT.h" +#include "controller.hpp" +#include "path.hpp" +#include "perception.hpp" +#include "sim.hpp" +#include "types.hpp" + +namespace py = pybind11; + +static CDT::EdgeUSet& get_offline_edges() { + return offline_inner_edges; +} +static CDT::EdgeUSet& get_boundary_edges() { + return offline_boundary_edges; +} +static std::vector& get_center_points() { + return center_points; +} +static double get_center_line_length() { + return center_line_length; +} + +PYBIND11_MODULE(Controller, m, py::mod_gil_not_used()) { + py::class_(m, "ControlOutput") + .def(py::init()) + .def_readwrite("ax", &ControlOutput::ax) + .def_readwrite("omega_dot", &ControlOutput::omega_dot); + + py::class_(m, "VehicleState") + .def(py::init<>()) + .def_readwrite("x", &VehicleState::x) + .def_readwrite("y", &VehicleState::y) + .def_readwrite("theta", &VehicleState::theta) + .def_readwrite("v_x", &VehicleState::v_x) + .def_readwrite("v_y", &VehicleState::v_y) + .def_readwrite("omega", &VehicleState::omega); + + py::enum_(m, "ConeColor") + .value("BLUE", ConeColor::BLUE) + .value("YELLOW", ConeColor::YELLOW) + .export_values(); + + py::class_(m, "Cone") + .def(py::init()) + .def_readwrite("x", &Cone::x) + .def_readwrite("y", &Cone::y) + .def_readwrite("c", &Cone::c); + + py::class_(m, "Edge") + .def("v1", &CDT::Edge::v1) + .def("v2", &CDT::Edge::v2); + + py::class_(m, "Location") + .def(py::init()) + .def_readwrite("x", &Location::x) + .def_readwrite("y", &Location::y); + + m.def("compute", &compute, R"pbdoc( + Compute control output + )pbdoc"); + + m.def("compute_path", &compute_path_from_percepted_cones, R"pbdoc() + Compute the triangulation from a list of cones + )pbdoc"); + + // debugging visualization purposes + m.def("get_offline_edges", &get_offline_edges, py::return_value_policy::reference, R"pbdoc() + Get the offline edges calculated from compute_path() + )pbdoc"); + m.def("get_boundary_edges", &get_boundary_edges, py::return_value_policy::reference, R"pbdoc( + Get the boundary edges calculated from compute_path() + )pbdoc"); + m.def("get_center_points", &get_center_points, py::return_value_policy::reference, R"pbdoc( + Get the center points calculated from compute_path() + )pbdoc"); + m.def("get_center_line_length", &get_center_line_length, R"pbdoc( + Get the length of the center line calculated from compute_path() + )pbdoc"); + + m.def("sim_step", &sim_step, R"pbdoc( + Simulate one step of the vehicle dynamics + )pbdoc"); + + m.def("project", [](const double a, const double b) { return project(a, b); }, R"pbdoc( + Project a point onto a line defined by two points + )pbdoc"); + m.def("project_seeded", [](const double a, const double b, const double c) { return project(a, b, c); }, R"pbdoc() + Project a point onto a line defined by two points, with a seed for the optimization algorithm + )pbdoc"); + m.def("spline_t", &spline_t, R"pbdoc() + Get the point on the center line corresponding to a given t + )pbdoc"); + + m.def("mock_perception", &mock_perception, R"pbdoc( + Mock the perception module by directly setting the list of cones + )pbdoc"); + + static py::exception ex(m, "Alglib::ApError"); + py::register_exception_translator([](std::exception_ptr p) { + try { + if (p) + std::rethrow_exception(p); + } catch (const alglib::ap_error& e) { + // Set the Python error using a custom field instead of .what() + ex(e.msg.c_str()); + } + }); +} \ No newline at end of file diff --git a/auto_sim/test_controller_2/pyproject.toml b/auto_sim/test_controller_2/pyproject.toml new file mode 100644 index 0000000..355770c --- /dev/null +++ b/auto_sim/test_controller_2/pyproject.toml @@ -0,0 +1,18 @@ +[build-system] +requires = [ + "setuptools>=42", + "pybind11>=2.10.0", +] +build-backend = "setuptools.build_meta" + +[tool.ruff] +target-version = "py313" + +[tool.ruff.lint] +extend-select = [ + "B", # flake8-bugbear + "I", # isort + "PGH", # pygrep-hooks + "RUF", # Ruff-specific + "UP", # pyupgrade +] \ No newline at end of file diff --git a/auto_sim/test_controller_2/scopetimer.hpp b/auto_sim/test_controller_2/scopetimer.hpp new file mode 100644 index 0000000..38b583e --- /dev/null +++ b/auto_sim/test_controller_2/scopetimer.hpp @@ -0,0 +1,21 @@ +#pragma once +#include +#include + +class ScopeTimer { +public: + // Constructor: Starts the timer + explicit ScopeTimer(const std::string& name) + : m_name(name), m_start_time(std::chrono::steady_clock::now()) { } + + // Destructor: Stops the timer and prints elapsed time + ~ScopeTimer() { + const auto end_time = std::chrono::steady_clock::now(); + const auto duration_us = std::chrono::duration_cast(end_time - m_start_time).count(); + std::cout << "Timer [" << m_name << "]: " << duration_us << " us" << std::endl; + } + +private: + std::string m_name; + std::chrono::time_point m_start_time; +}; \ No newline at end of file diff --git a/auto_sim/test_controller_2/setup.py b/auto_sim/test_controller_2/setup.py new file mode 100644 index 0000000..5179022 --- /dev/null +++ b/auto_sim/test_controller_2/setup.py @@ -0,0 +1,41 @@ +# Available at setup time due to pyproject.toml +from pybind11.setup_helpers import Pybind11Extension, build_ext +from setuptools import setup + +__version__ = "0.0.1" + +# get all sources in the build/_deps/alglib-src/alglib/src directory +import os + +alglib_srcs = [] +for root, dirs, files in os.walk("build/_deps/alglib-src/src"): + for file in files: + if file.endswith(".cpp"): + alglib_srcs.append(os.path.join(root, file)) +print(alglib_srcs) + +ext_modules = [ + Pybind11Extension( + "Controller", + ["pybind.cpp", "sim.cpp", "controller.cpp", "path.cpp", "perception.cpp"] + alglib_srcs, + include_dirs=[".", "build/_deps/cdt-src/CDT/include", "build/_deps/alglib-src/src"], + language="c++", + ), +] + +setup( + name="Controller", + version=__version__, + author="Edwin Zheng", + author_email="ezheng09@student.ubc.ca", + url="https://github.com/UBCFormulaElectric/sim", + description="A simple controller for testing", + long_description="", + ext_modules=ext_modules, + extras_require={"test": "pytest"}, + # Currently, build_ext only provides an optional "highest supported C++ + # level" feature, but in the future it may provide more features. + cmdclass={"build_ext": build_ext}, + zip_safe=False, + python_requires=">=3.9", +) diff --git a/auto_sim/test_controller_2/sim.cpp b/auto_sim/test_controller_2/sim.cpp new file mode 100644 index 0000000..6978b08 --- /dev/null +++ b/auto_sim/test_controller_2/sim.cpp @@ -0,0 +1,19 @@ +#include "sim.hpp" +#include +#include + +void sim_step(VehicleState& state, const ControlOutput& control, const int dt) +{ + const double dt_s = dt / 1000.0; + state.v_x += (control.ax + state.omega * state.v_y) * dt_s; + + const double beta = std::atan2(state.v_y, state.v_x); + const double tire_ay = -1 * beta; // simple tire model for lateral forces + state.v_y += (tire_ay - state.omega * state.v_x) * dt_s; + + state.theta += std::fmod(state.omega * dt_s, 2 * std::numbers::pi); + const double v_x_world = state.v_x * std::cos(state.theta) - state.v_y * std::sin(state.theta); + const double v_y_world = state.v_x * std::sin(state.theta) + state.v_y * std::cos(state.theta); + state.x += v_x_world * dt_s; + state.y += v_y_world * dt_s; +} \ No newline at end of file diff --git a/auto_sim/test_controller_2/sim.hpp b/auto_sim/test_controller_2/sim.hpp new file mode 100644 index 0000000..e64c29e --- /dev/null +++ b/auto_sim/test_controller_2/sim.hpp @@ -0,0 +1,4 @@ +#pragma once +#include "types.hpp" + +void sim_step(VehicleState& state, const ControlOutput& control, const int dt); \ No newline at end of file diff --git a/auto_sim/test_controller_2/types.hpp b/auto_sim/test_controller_2/types.hpp new file mode 100644 index 0000000..a65f1ea --- /dev/null +++ b/auto_sim/test_controller_2/types.hpp @@ -0,0 +1,38 @@ +#pragma once + +struct ControlOutput { + // in local frame + double ax; + // no frame + double omega_dot; + ControlOutput(const double _ax, const double _omega_dot) + : ax(_ax), omega_dot(_omega_dot) { } +}; + +struct VehicleState { + // in global frame + double x; + double y; + double theta; + // in local frame + double v_x; + double v_y; + // no frame + double omega; + VehicleState() + : x(0), y(0), theta(0), v_x(0), v_y(0), omega(0) { } +}; + +enum class ConeColor { + BLUE, + YELLOW, + ORANGE, + CENTER +}; +struct Cone { + double x; + double y; + ConeColor c; + Cone(const double _x, const double _y, const ConeColor _c) + : x(_x), y(_y), c(_c) { } +}; \ No newline at end of file diff --git a/auto_sim/vignette.png b/auto_sim/vignette.png new file mode 100644 index 0000000..a0e0ed0 Binary files /dev/null and b/auto_sim/vignette.png differ