diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 57b1a30..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build/ -*txt.user diff --git a/1 b/1 new file mode 100644 index 0000000..31a805d --- /dev/null +++ b/1 @@ -0,0 +1 @@ +W1%k+i \ No newline at end of file diff --git a/2 b/2 new file mode 100644 index 0000000..7889e1f --- /dev/null +++ b/2 @@ -0,0 +1 @@ +G0lXe3%* \ No newline at end of file diff --git a/3 b/3 new file mode 100644 index 0000000..8a68804 --- /dev/null +++ b/3 @@ -0,0 +1,25 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +Related Commits +3e2983681d88af4116761583d7a84fab026d92a9 62533412f54c20a048841a543afee0ccb8019bbb 106238f734916650bd793ffb40e6133d8b385a1f d0d8be311bacba17a4fd3f73dbb75a2fa55d77d7 52d430f63fc0c2032649ca9274016bb48c8c576c d3c93430a19b95d70128de14896cacbfa16f660a ee8ca17372d41e695d654f8a32c18e5f7f0a4f72 8240c28dbf151ae1418cb5a7e15e4599a1566315 156f31d03b328b70468d5518ce52087021584113 cc3ac4e62734c2fd30403cb98844a904ade0b9e2 30b307ab1c2622410c4b645818a02a8e00a1a9eb f8bb551ea8a6b9f20c4dc851ba6e9db652565752 c19bf3a20408045cc49665a6297fcda7badd6223 e1f09f5cdccbac9b801701fad29fba0e876ee05c 35ed010d52d2bfbbc9f8c89152b6c9c7a7c18875 f1c71a0d74a8718203250dacbd458209b989c1bf db3ff3659fac937f094d83f981dc8fe6dfddeec9 182090c7a558f4de6f492ca3eacfc2b1266d87b1 a17528087712735dca55f6f447a9098196dffb11 3bd5f1e415dab7e72587531addf52747a0788904 4326c11b8e0123cfb5bcea644a43618877e06a07 ffee9fdb15c49da57c0120798ac2cc2745ae4edf 35f775421d5c1e6afb76d059601c3a9c65909b88 eeb5cf396df27c0e04fbfba1973b4473272adbfc a32b75e8a585c5d9314750601f19c7135353940c e9f0f23e9d04ef8f19de7bc20ee6fe4b2b9d30c3 45a610aea1ec7e3f980488a990dec1cc7e69ebfb 6b638de532d587b6db2b28bd1bfc3e53b4dc141e 3c3322de1a02b5bf0874cf611d2ce64e4d77d938 792e5b9b0fea4e99517379c00b0fbac8853a45ea b0759b7302799bd7c49a2a849e52562a67ed543d 2c8fcc9a2abb8e1de32054d2ec1fbae8d7fdb0e4 25437bd14f24f4102f8f42cb9b2c47b71861406c 8e9968910e8aa7b9111f99264a00c1146798fadf 4a834e5bfd72a6c968de73728a0d9973545bcf1b f8a5dbe8f2f76db8cbf790df7394f93d1df8a4da e9c66cce09f2c2daa7761aa4ffc19a271f91abf4 b7674330f6791d5d529990eeb51f372ed7472e39 ac69cfcdc28a5d3bcf5bfcde5a61fa96280f725f 228eb7e3d4fd55b59ba4bcd7d7e58d25a8073bc2 3368bf51083815a4a2d794771732e6c68e59d435 09722e3561fd6975869a0eb7820106119d7b7986 f8c77b02a81f25e3f73574b343a582d8fd204665 3523ab8fda444baaf33283c8c14e296bbded9015 dc4301ffc076a930de86cd51d21ad7f13ac44195 ea53145156c3c7eb50c725f44591b4e7c57167fc 73ec7b7500dc55908c6058d774d4e8b1e95ccfa1 9fc551bc5f505c1d3b73cb3d7c315794d90d2f1f 9bed87e6e60a86bab5ee9a3cbfc3ccd6ba13180b 36ffe6b772673c4f5575296aec85dacae8d9c209 57adc6448f2e71d82fa60294ea097c806d1eb967 923e80c891151a87dcd3a98da515e8c0d41efdeb 1f02e9a7a94c92b47c644ee12d603b79505f824c ae43dcd878abad5db3ad676cac91b54774240f17 ada9dd887d6919b66946544634826f7c2c3e1b48 784f2dc554019ff7779e48977939bf93c922b4a5 89e854bbe7a7b47cb1c2ec01fe12c68bfa9ce6f2 2e00fda57c0f3c4c6e45776c4c01137ae8d8e484 15a0378edbc4833e422c62b24e6a0c08bcc3407f b334e3eb459afc7f1e158a42d0f3e63dab812ad2 7ceac754b7d727c9910614e61307a7ba24263875 59fd08b17937d60efadd29f4c0d0e73fd4695128 00f5969c543978e0512cbe28b8a31a01f683099f 0a9d3329494e84277df34f546298dac727a28071 6c675a72e8486931425d555c6fc4a652a5a15f16 5aef653842d08eacbe01ee42da83119c239bf498 e4be8e2a3d0a1c5fc292bd2c70d793cfdfef6f59 d540694cd8a57bf97b46cdf7588597f21086f10c 96bee07167bd4bc08648e9ea995393bfb7ba5db4 9a1dfac535d3f3ba057767005952b8ae2e624f61 c49e7fe3b3ace35b3168bdf357181a375a0b243d dc3ea2e61b484009bd19cff675640baeaa644d75 0f02a5cae6b38d5e745ef0cb0f9030cabb48180d 89e5256a58431346c8175711304088734e5d9933 6d0f2ab2945740c4769279483acb6e84db559cd1 a982e8b95785b1a7754d0cc52e8b6914a290810d 9c54a9a51aaaff6ccaf4a93e927faae5e5072b30 6dd6bdd1796c853e779dbf8600ff556999a8415a 39efce0abc5d23b40bf58ed64adec8213a511373 a7dd1e6e95d9027378449635f8958c648315a6ca f2dcf439386a63561d009e82e808f51ec47b0c83 2c2c653b06aacaba5003f6af79f472b684624362 d0f4715fd0e30c5253af6490af3b3cc280bc41b5 25d9dad1fbea2f3778d6594cdf72de1c836b9e70 cbad73874c7c10b1af6782eeac6cb571e17abfc5 c320d4a248e3117476d946f913211d9c627b7e6d 14ed76e257399c8af75193d801bdc4600269af5d b5f66a8fd02ab73383345ff74ea7d97edfb6a349 b7127a4a3ce00800c31f069fdc7ab30340214192 ec5a9ada63486f2efcbc05661e9207f5fea546a2 032088966379dd244eb905ba7233c27291cefdbd 70792c241b25a69e0f8a3363719afd2d5dacac3e 059cbf270070456aadd40dd3cfad50a5440b2fad 7e3c137222899f17aa95d7d4ffcf1bf8a37d9389 ffdee402262298a1171b33138810a842f828dd17 d11c072cb3dc17f894c81d84199e1b090f0bf1fc 8002a6bd6b3d8ec78016fad88396e09004874d57 976e62466f222b12effbb457ed3e34942a13de3e 5399cb6991f86cbd0cca15f83946dd2cd402a523 2b3ea873a2d54a2f9f7bab1263618a2317f5c851 e2fd2f6eace7c83ea3e8eb549fbf888a4e7188a6 b00f757fc6b3f5fdb61810a706417a697fd513fd eca88d22f0f26505be6c730f4d4f159a519faf41 6a7922104e9b2d03990f213a7d0a2dcf45192bfc a1c20cdc0e7ce90f79a6c80860e905974051f4d8 18450e8a59c204d219dbf56754e9e88a461028a4 da05b45bcf3120fdf80da030ea9984e2e1666006 394228bb1ba5fef377f536c165dfa827af2c5b84 f915e5f2088292f78a763dadf0bb863693acefa3 a90545cab5a482d824ef2fd56a05b24aeeb06c38 ea7d701560c1991cf3a465e5a437f1a00f480540 d72c7945b2747fc0baf13053f443e3e8a40a90c0 21e5891b54d9616e6d69fb240dc15f6d334bbcb3 b5d9eb69875519244a552e516626650c5eddace1 00f80b8bc96560984b0ffc2ed37de1fdb750b002 69d74ec49ded1c9cbec563b809d72c7371c613a2 adcea73374d7f05aecbb07b3ad104dcafb2b8e43 0b4ae9dc049dc65c3e329346cf89b1453e92bcbc 5dc2759611931f1daae10942908d67505d616304 4fcd17e5158699e6aab4f0ffe7b7f8922b4dc733 2aed76a38851a4737988ae83004a8eafdafda712 2b6026e2d5d6e7252dc9a90de746e27d9b53cec2 55f39d4a1e6fe952f88385b38e4b2edc85695231 7889a6075c20b066182af69cf688d07b51cc626a 6f0109ef9f5630d294c2fd3026e65e8b8886d4ae d6bdf17a9476026467fcb3bc787aa3096cc54fd6 218e2b96a05b91647209ae045f856233a1ae29c8 edba53b871b99fe97170f753afb7b0877b47a964 ef5ba0055e5fe8534fdbd1c830aa02ac71b803d0 f0d9635c2ea4c2fe7a15b990d1db6f1722a6c5c8 b18fa17dfcbc12c8183ec70278bb16f1bad39626 7feca35ffb42f8b0a94f1060d0bd7438a376845e b794e5674eb72ddec2f47be08263c4d6da1bee34 8b61c1761bba5d47cb1a8ec8fc97f676b8970495 63c4304aa72c9db11042a7f43f277f1807e48333 4d1588fbf504038048e255fd1b5b160a56a1ff12 b3f6ae40b57d6c84528f5f499db3f285926abadd d79da881b0854f3590b83edbb37621be8f2a7ec4 69ae92e1e62c16f82780697534d117c9bfb7fb16 038e4435efc4c6d4c7a6e2bb75ea00673852548b ea8031a9bbc9820816aadfc79230e5d920554d44 21037f05639b4fdc9bf5406023fa1455fd9d6b2d 74114498351888210b4755632ce5b6418e12d6d1 ec67cf108e4b8bd0cf5d4dad53b926b3bcbb92a9 8492c6c7336c3dba7511046b363c558fdbc7d16c 8055a458d9ebfaed4b1ed1521711b406c470cee2 ceba8489ac7d4747b3560437266c8a764cb14fee 37454ea46b0135ae340617f4821d5fde5aea94ef f561740931d01673e809197f4e111238750ff105 999288961d4a998d9162670adbd26c33e7134a02 3650628c11720d612d76944067d6c7d64a1b39da 8eaf214617cffd637209699c8a524220b2ebb4ad 6cadf78370b844ee1885475a76c49b3c0ad436ca a9362b47fdb8e5f0c6724f8de8ec1f3bbecc5253 8386ce7745606241acd0689a13bde8117dbd6acc efe0ad3d3947f79d530a66a2d376f34b6a11581a 202b7bd1f3d77ad3016a249d3f65fead94b4ef7b 14ae18d415926bf91fa0efc59e4d266fefffd6c7 b3d24ba93b26308fafeb6c243472ad6dbe9c5e97 2090e1b61de272e50bdf6c54c8ed47e692a6f0d1 62e441e49027d69e23dea65a993d617957192aca 2b27a9079d0b82eaf1717a3bb4d203d054ad57f9 469c3e73536485c8fe00bb8dc1393921db49b59c afdc4e994c2261e74a549248c4b1ad777a5a6f48 f44e2a09e62a091f25646ccb7d76120c51e6742d 840d7d6b14038d5a1c48bf91d5add31dbfb89668 ba879a5f5b239c43ec9a61567f3775664cddb3d1 ec68f80be249d4801a326e3aa2ee1ba8cb8d1167 eaba462cbdbedc9c75c9b554b91eb546361a7e6c ed24a207e21288708dbbadcfac620a71045e82fd 3f16ddfcedf1437b94a7bbfc97f479009a26c6f7 47e9ba762b994c423e1a9018d2654f3abafbda50 8a34c29c9828619167d600f8ce99175ddc601090 c179384f6b4ca3f85e641b1e3e00e9c84f010667 302b6bb3b7ef8bea75ed8e872d8bee4138c8ab6d 46cc0e293a313d4058948e9039e3a9a00c9b6bc7 a13bbfd297117edb742e5bb5990ff2ca39ae715d 94f08a2a115a809ac0caeacd44de2796dc778b26 d5ab574933234205464015d3e7a4851de24e17cf 8e74fd0fd753a19dc3fb20769ef79be0f41303fe 770be891e060a8538a1cd1b7d8424cb85cc835fe 12a9adb05f3d1e347c4e73545593b9830c7cfc15 6b8a8e288d9a406abb540269c15016390704a041 19589f03f91bde04ca93bbc5fb2a4533c5eb161f 88ebda5c47d653656343b77acf38f17cddb5bb65 75011ad6b570548d5f8c027d9f36d48579945f75 2b2524ca7f4046a3b895e5878c7535bc45743d79 c1bc26d472d38b635451e5dcd50e358055757554 8a4bb9e82063619c6e3f43bf0a64b06e109cc4f5 40e2dc9e689b27789990355839c148f58e60c16a 692e9f30130c0ff43f49f0bc45ac5a0daef9ad41 1d0d088371f0fa85b749369df24c7ec0ea6207c7 161f09ff448b4d217649bd721900d43381f3f6ec 2dbe0a788a9dea17abb2ac8c2958c9f5917b96c8 10a22835e910bef2fa763565baf5d0925e51d100 3c28ac007b073d654ab4624aff5e4c64c42d25a9 7bcd7f1a630fc62aeaf54994ffe3cde31fb283a3 18c7375afec817b51963dd0c3b8de313b9e9bd42 b6f540dadd55776a103aefd5def182e8832202a9 d3e9ecd28d5f6a547ba7e2419470c77cadb6955e 7b2c3b730c6c30d30ebe415a76d5aea7f4f4d32b f64a7f92747f5bbfc00c576d38edb7193e1c3bc1 237bcdd0afd8ab7d13a17783a6af6a0bcf77229f 83ae4c63218ce2d0da47aacd971a735cea29a11b 5d9454d69dce8347bd59f99779df0f1b8c7566c2 51fe2ffc7e4761c06b896c82fc625fdff57d686c 49d396ba7aaf4b50ff6352691351063837a18212 5020cbae9ca63e7386d78e7259ce73e8dd7773c7 dda87d03bd7e514059819a23af40989db855cc38 933fc4d5f48d81a48d8457ca67451e0d6395fca2 7ff5c5e8d82f73752484b9beba310839afec3bf5 c964271cbda83a66cba050e8582934e177e78773 39aaed9ce72aa1ec4438054d86f9f4d1abfa910d 3047688c5bb8e53f155f62de3c5fc49064e92f55 a7942007265e81307c94597ceec121ca699852da 614177f474693f5553016156b7343ea2ad88a0b1 08631cac3d9860d26b7a8b7c090365ff21ef8a03 df4a6f53c7ccf57e577bd4f6c27d7ba015e1aa1d 42f22fb2a303025afe3832305bae48777eb7003f 31c12e22ea4a84a5901c9f1862d2e7f682a0b364 1d6161ddd05669ca72b9787d3a3385c3214c71bf e5e1f8e2e32c8caf9c23b6ca01eb528899926960 65c1cd326fa53671d44f5a20790d1c4970695f84 bb2f51d45b68b43959f74beaf0e55c51c549fe3d 998b87276fb7c55c6e58e606c0501137d3abd99d 88951afddaa674841f54de867c88e9ee40460dc8 57f923b4bd8926f0e44d9f4a1e770ae40b5a844a a4a82537ab4af1e3dde8c0643099406d7d580848 53eaf5ebf31e5e63c8719825dac6abeb949bee0a 41758a99f7a83bf61cb0ec2577a6fb9f3e3ff0a1 cb1614214d45fc8532a7d548e7bd79b960e56944 8a9eaa02dd866c6870e14aa03a11634efbd85102 35771bfcda68fe1f107c092442ebdbff6a8c250b 9da4b31b2f19e135dfbd1060cd6cc4698583e451 bd8ed99a8c42cf1d6cb779da5fcc8371d8fd8767 ffa156588e9192a64251db120709358f27b023fe 68566814048e439154c25397be04da9d26de34ad 00b48a10c4bf9018c239ae23af4a59cd0c6a9e7e 237aff91c3375407e89988a825c03d1f54bb26e6 d29c4e1e5d0bd7b82f1571671ace20af9de50130 f706cf3623760e52691d2500f99106d697fcc95d c69bb0f66487625c716f833528646b977ee13d89 b1c8de2a553fd011ee903512d7907e0ddd206bfa d844efb95fe92556af18bbc8b29c45710487d9fc 71a74f36769574a6f8b8f7092056657705175bb1 67af848f7b6d0a9d30b49561f5588f1c54c661c5 4323fe4d8f2f4833ebb71b45a9efaad460bb404f 1b0af2a39a8cf45f456d7c43907c7009ebcc42c9 d63e6a9254610b9e16b4c6c4ca9feb462700c9c1 061e8788232057716aaea5d8459c6ceafc4d599a b7205571f70da64ff5746ea1edd100cf7f071717 967a4c5c9315c86c3f58fda22f986efe558c3cf0 7895409496eb2485bcf7bbdc99b13c5e9e2ee8a0 83e757965446ef1316b9211e7f0df9fd5b103865 20bd220d49f057a72c2feeaeb821189d11f52eff ea766f2c2c2619d8d63c4ecca6310f120fcd2046 02d5abca5f98cb6e9d65a6c2f3de8959016bb1ef 52a9341747577addc1be31683980732280b422de 923dbcce925b9b46c75b829396b0942c1b2494a0 8930ebaf45c2d1fd2c0bb8eca0ee49ed5a537e57 df9acfba962f679240f413b9c78e66448bffec57 ea3de4611b446a0139578cdcbc757ea5df3b0870 5a1f82fc641d515df968140f6555122f7e7c7a56 7f82fe7ab442736386225cd4f6a159a6ace38776 83354d5917871ce23872d8603023e24d3a8d644b 995db0a92a36de7b1ef0ebb25d62a0d780f91f35 f3406177a234e5958673caaf9c6768d1a7edc258 c2872e7d3e26fbeb41a503dda620f7e5e18d861b 138eb24d4deefd9cd69b1444b67121d0da750e39 d8d81f21e33d54e45d6142171bcfbbcfbd0dd278 b044049bf9853de8957d75fdd6eb1eb4f5332b87 a63092d20c7d547c1cab93bae5c0a175e35257b0 85f4a97b4d588deae56b92752406c6fd2aaaaba1 532fb1e7406aaff5b6cb7343fe682dd009bf2aa1 427891a02d697618a7a43c4851c28aab7c99d99f c95de066bad7aedc14651c2407ef23b8b9e3e57b 3095db053d42ffdd7c9876af002c32e8aaf8eba3 5eee146bc5b35805763e191b97bbc24f3b231a31 b540cadc6157c176d700edeb60d1f39422b40b18 c712e26684aed3ccf430e8468d724d7ab7d5daf7 b2797cafa6dda966614a4db3da4fafc3cbd4e8f4 cbe6defd3207f2f11ecf8269cc67dec97fe98400 74dac97da95db43648af2a89f4af0d8d8ce01474 fef6d8a0610cc941fc2be7349ec77d48cb0e1875 d02fe685497761715a1f7307fea2ee00f6d0ab2b 69e8f84117065ca070b61cb4c70bfa122bcdfefd 3e683027994219ca829c837ca9722a974d9a952a 3e631eaf4bebfd928ceef82ad69bbba272a08ec3 ea3e218bf69ca298d0be29892a6fe378e5a3900b fc13acdb63a2d988c156adece5f78a651eed77cd dc13b818d7996922c2ba3bbdedad53ae3b7c4bab 9c6b6d6bb23f89bb7b07a9fdbc4b09ab0413a515 40c85733f3d96b700b1846ea7d059ec7d2ff24be ec2f2d2a8ea39dc71d6b126804d00d0dc284339e 3a59eeeafd7f9860b374fc441a491a9514a58297 80556970aa5436de39c65bdc010acebd88899e73 bb19f4b437578beb519a1e12ed0e9e23aeef331c 96f51761cdd62505b676ae235c5785831a2e5427 52bfa28bbdf5e8aff5153bb53e1494e3da8838cf c6b1e19d4d6f1952bb4b690b877213c76343c54e 501ed3289e0119b84e57fd01cba959e67caf5f78 d91cf1d47edf697c5aeb0cc77ebd61bcb7391872 fab0ae72dc8d1444d2610e914c3015009dca1ee7 328a554c31cc071fe17dd91ff71521bb6aa1c774 42575195facd61b864b8ffe4384a1b2f3d4f7648 aa03be728bd8c525b29789638c0f0de8a27d28ec 88276b5ae9b5385bf7a1c40f6b03045d90ff2893 c1f83283458b2db3094b382bae3fdddf542ed207 80d8cda2a2cfe0533751416cae24e35c8091faa3 34f05475294f9e2d6e37c669dfa3101b87f0d712 8d788d025975834c0edeefda5a7e0ecd404c3a85 569f4b11d6acddceedb73f0444df7b9366a43191 db57d544ae4396bbbd5ac97cfe12cad7c8db69ed 54f57737dbbd6e7e8e342bb2d26b9a6d7724506e 963a48f4f18d1b1c6b339c19e908dba506f8d6a0 00860a23f69ebc01287948258177db4f7c51e0cd 3f38b178a7200342ab65bda82735a8cd21dd222c b626ce024fed5a5a05f5d13d60506440c9a09e38 ddb9800e7a6063d3532b384cc4fc9da75b2ad6b7 236cef11d6ec692198260395a7d1c0697ab2ebab 07b4de8eede971c8497031ea4bbb1b9e8a913e17 7d923d56908043faeea3e6039f47a2ff0669a94b 174ef8e7c12c2dc7b59fe3eaccfa5636b11f31bc 79fd1dd7b0ac8791b6e65297aadf2bbd6071bfa6 4ff546b54e262ce636a0b912a5f23978b618f31e aabad0ac48bf5144819c307c91ff0f5ea14ba068 037f52d0e372af918a059670fc1dcb5dd258677c c823ce7b41861a16bf99e6085f99cf46f984ccc6 2fb4a33513b6a241c3816a99053d44e406f81ba7 b00203cb368b2fc1a5d81aef43e05047d4e1a975 b95b42140d632d54819d4125f627aac237870311 e0dc45c876c09da462d9081ce6781f009d0f95c5 a8003163ae21216a21ad5a1f3081c45f138dd231 979ed86f2d79675d4bfa034d820beccc0f17189c 518cbc7255fa90493163c1f16bbe43f5a12d4b5c 06c307144df18e50b17bdd0e73853d3b42c40012 d863c9bbb8390debebbff723d142731878a03a08 c759a29dcd971f8293137ff314d4c0aabcc0d5d3 ee68f958082ed7761f4e5dd60bfc56c46bc21682 91b63e4401fd674cbc14db9a79e7836acebcfab2 ac91f9797d8fef487bb713c59fa0f8fde2faf172 75cdac450be210261a2a9570fd1cf4b0171e9f60 b243c261e6fe3baacf1b55df0188d70efebcf2ae 1f4ee0b145857933fa511747fc4a101014b8fd4d a5b159b73ae51059fe01d309444e9dc840ba253d 04605216776095d53b1fd36d9a0b8097e403be9e f5ce7643d85e9a9de60d5e05406dc4762500e382 fb3633bd67220e49e170b93688eb90a1c6e09cbf 5158bd0f780727d5bb7af4f24601c7734a368bc3 60c2cd3e8e598d3dac95bd9a940240b2d3c6d767 73fa2bd272141db28c62065f2da012daf5322ef6 1d5dc04bfeb696da99827b26230b25df84f17c56 0d25e1d7db3668a7ed3093700c933ad100a66579 aceb646d45aa08137a41444e73ccfbd736f2a74e f5321cc6e9ab6878d0ec63adfc4d3d1dec168a5e 3e60cde25032ff2389a1ceb0095472395f092bba 19c6a49431467cc57fca16f77eedc72aeb6aa3ad ad20ab84060774c29f80ff1b769a26679fff2b19 c2b21c8c502da2d55bdb0f4372f245fbcdc5ff94 20038d60a029f911942ea62b4e08a975882b0dad 8f925a689013963b0026db84031c4d392cb8f777 72600c0e2f662c575d9e413590f444d061f07e9b 02703ac9c46b6d677264a339d19ff9c7123dc9d9 6ded820dc52da2039ee7bc633346afcd8a3206e1 +Branch:feature/forgo-stdout +HEAD:3e2983681d88af4116761583d7a84fab026d92a9 +PREV_HASH:25971f91a92adfa88d7a590ca861b36c29fd22b013a993002dcaaa176f27a06d2131e08e0a604f3c0b8612db1abce5062508e82e160a37ca68726c2de73c5170 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQIcBAEBCAAGBQJaBKZWAAoJEGiDGwFKJ1qdgtUP/jMFgyQAYDQU7R0/2MvPlyrW +YhExMbm1stxfJyHnofKQoXtzoEy6KJ2NmjTpkP6EuHWZiYlkBlsssuVmjSfGGmWV +D3cfrdIYKHDrQB4mlxl5IX5LHCrE5BOp8/MfY9XIk2lIFtNSzymMbq6yt0uCTp/p +qGZrYF8UCBy5B1iYEIJEW433V0XyLWMONtzKFwdUDu/1FX1uJE/ASVXu6OuZjSz4 +/+fpX2pBgqVqEu8SPO+Zhz1di1UuUGDb890OuTvmLKk/z2wd2YliEgXLLHaQYc4u +AxQ3BbKf0QJAmt7lXWCq4yJlZfmD+3wIHs+WRbaHQyOItFAs0iI0ztPKPTeJCwIN +wvB84CamGm1Xy1xVlYR06cy2tiGF2ldmIEEt2ZCAfX2owvf3QoLGzUzGT9aLlA4i +qLa9ui+xpggAvMdKJ+kTp7aVtZlBaI10uN85hJ3a6H+RJyekhmlkQSEAuW88VxCJ +sR8lnDS+cMHWtcE/OclEodkIZyfuv4v+aHwsMDTxIdcWvJbe4YqsU0vdmn+9roKR +Iwr4dwJcCcT0ZaffD2TreP/28F/+sDlgxWXREs/0cFDhJr6IAimjUoTX1gEq9rF/ +hLmZC1mCKUEL2Gnim1YeKGOVPpV6aBlWkk158/0fLSjAhQ4D8WeNYfKeqdTK3HZ6 +Y8ayqa1UGWcYX0qTPNrV +=gG9K +-----END PGP SIGNATURE----- diff --git a/4 b/4 new file mode 100644 index 0000000..8da66c2 --- /dev/null +++ b/4 @@ -0,0 +1,25 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +Related Commits +dc5d4b04830ec2755fd247fd62271612bad56b9d +Branch:feature/forgo-stdout +HEAD:dc5d4b04830ec2755fd247fd62271612bad56b9d +PREV_HASH:1556d8ebfabdd8cdfe012ef5815a3a883b13e14b96d61a29d5af360053504a7eeb71e1e7fcb658d9bfc2edfe114d822a4cb1686599897bdc4adacf15a74aae0d +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQIcBAEBCAAGBQJaBKeDAAoJEGiDGwFKJ1qdKUIP/1a6kRwrz1SaNn62ebh4vET3 +f40WUf9zl4HBltzIBNG62R5c8aD5FACDyjEy4uB6xvTGo6oh8ETr1GRjD4/PwUon +GcdAaLvvx8dTeuG+ZALPTS7cgMLSgxD6q9te8S0+PcZD63m8VffH624NAht7QdmM +kCRwj4tlfoKjO+kU2UkM6DvlHABYJA3Zg7pMNdAL3mOsymK5TurZIpXLJEunSp9p +DY9vB4ZscojkrUfoF+1wcCIUpYi5liQQtLblFp5hAmS8iCOvfiTdBuMDldsRJWj8 +tO6X1IZMbfw39Zx/15MogUNQDYrILclj5uoTUG3eELJuQWTea4hpKLXN76sAP4hb +KRSrtsB0WT9yzcBE6jR+MjTuIMW5ROn2G+t5J27nTce5YAjdTnl1in/zhKc+bNkK +ZGy5rlyEtTVMOKYPvF9f4HWy0FN4fUkKsDxoC96kkM0qLC2lFVqxz35A8o5K6o1J +c3PFrRtGlve8DyMibQ9OqXEEDNP6deSVh5+/AQRRRTJFmWDy0y4kn3NwiYoXkzNF +7WrYNDXhNL84/Db5NuzIQeaygw1Z/yBi8rloorfaVhh+MFMhfXSnRsq48lteXV2O +sHOhg/t/Mr4ITPRLiD6+y4eD9GyHfOYtoRzVBX50IhfRrikP0dnG0YYqalI/uJEM +JREdO/mZN+HFUjsVYFfx +=N2Cj +-----END PGP SIGNATURE----- diff --git a/5 b/5 new file mode 100644 index 0000000..c3583ec --- /dev/null +++ b/5 @@ -0,0 +1,25 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +Related Commits +130f565ce2ff171066a7a3284cefa985fe8770f5 +Branch:feature/forgo-stdout +HEAD:130f565ce2ff171066a7a3284cefa985fe8770f5 +PREV_HASH:013b92a89acbcf1cef50b3260282ae4bee70895b04b51fec093e09cd6b7b66dadfb61c3bb111398149c3550c7226370ee5646e993772c9176317d7a2c018705a +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQIcBAEBCAAGBQJaBLNoAAoJEGiDGwFKJ1qdIFMQAKdGnbjDFkrq+AHED7qBeJQN +2XAT9UR8tNVPHR7hGsn+V/mdz/igaHOrcmSILjjXH0mTcBUYk8DjC1WpGg7v69vM +QPe1XHbBHn2p4SgmxqayyhS1mk3Hrqs3jazK4PikoqmKRcG/c2xe7ycrhe0JExJZ +2ZVKXlpOERiCiPJiqQQXRpr/eg4TWFVnZzuukBOeAarS2jbPvZbz3MkC5MPG3HmN +FESBVm+Tf/T1WS3GEs+9vl28qGMD5xzPzLkIEn7H3s62CK+th24miAM9Y1BMHHdl +NmthnMsVAa7xDzfewQZPxaL705cWdDi3HuCXXqaAXNSj/h6yb4op87uk+6IOLIAU +zFIAlSrOPiFfJkhyUCan21kjF+SQQlNDMUFfqU5GLNPGcVnrVAAQ5jNHKFK7So3K +OxB+GD7YqH+C9KbG+kWx9/AbHbk+z6V7DnuI3/GpNludgp177KrQLKmBfony7v3o +qFKWOONXtSWySqEKdmn5MRaEZSMcrGRE29Ar6FhTr1a7uQWNbTMB2DT0373U89uf +l3nTLk/LsLGw/mhTgfPra7WmVt+7F9PYpCKd+j0uxtLhWfcBfIi9Dt6dX9s4i6Jq +YXjlkQlUMjo8XZD/NGwA7M5ja5M5jP/EIcBut7nx0u4zFgMC79KwfeJ9fRppKlrH +fEP7u+nTk2XV0Jev+BmA +=U+CL +-----END PGP SIGNATURE----- diff --git a/6 b/6 new file mode 100644 index 0000000..92ad272 --- /dev/null +++ b/6 @@ -0,0 +1 @@ +1e[7 \ No newline at end of file diff --git a/7 b/7 new file mode 100644 index 0000000..63aebb0 --- /dev/null +++ b/7 @@ -0,0 +1,2 @@ + N,~sX + \ No newline at end of file diff --git a/8 b/8 new file mode 100644 index 0000000..b5ff9be --- /dev/null +++ b/8 @@ -0,0 +1 @@ +̳(ZU ͖ \ No newline at end of file diff --git a/9 b/9 new file mode 100644 index 0000000..197ab6f --- /dev/null +++ b/9 @@ -0,0 +1,25 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +Related Commits +2981c3c1b2f416c222bb087ae5c3f24045770439 130f565ce2ff171066a7a3284cefa985fe8770f5 dc5d4b04830ec2755fd247fd62271612bad56b9d 3e2983681d88af4116761583d7a84fab026d92a9 62533412f54c20a048841a543afee0ccb8019bbb 106238f734916650bd793ffb40e6133d8b385a1f d0d8be311bacba17a4fd3f73dbb75a2fa55d77d7 52d430f63fc0c2032649ca9274016bb48c8c576c d3c93430a19b95d70128de14896cacbfa16f660a ee8ca17372d41e695d654f8a32c18e5f7f0a4f72 8240c28dbf151ae1418cb5a7e15e4599a1566315 156f31d03b328b70468d5518ce52087021584113 cc3ac4e62734c2fd30403cb98844a904ade0b9e2 30b307ab1c2622410c4b645818a02a8e00a1a9eb f8bb551ea8a6b9f20c4dc851ba6e9db652565752 c19bf3a20408045cc49665a6297fcda7badd6223 e1f09f5cdccbac9b801701fad29fba0e876ee05c 35ed010d52d2bfbbc9f8c89152b6c9c7a7c18875 f1c71a0d74a8718203250dacbd458209b989c1bf db3ff3659fac937f094d83f981dc8fe6dfddeec9 182090c7a558f4de6f492ca3eacfc2b1266d87b1 a17528087712735dca55f6f447a9098196dffb11 3bd5f1e415dab7e72587531addf52747a0788904 4326c11b8e0123cfb5bcea644a43618877e06a07 ffee9fdb15c49da57c0120798ac2cc2745ae4edf 35f775421d5c1e6afb76d059601c3a9c65909b88 eeb5cf396df27c0e04fbfba1973b4473272adbfc a32b75e8a585c5d9314750601f19c7135353940c e9f0f23e9d04ef8f19de7bc20ee6fe4b2b9d30c3 45a610aea1ec7e3f980488a990dec1cc7e69ebfb 6b638de532d587b6db2b28bd1bfc3e53b4dc141e 3c3322de1a02b5bf0874cf611d2ce64e4d77d938 792e5b9b0fea4e99517379c00b0fbac8853a45ea b0759b7302799bd7c49a2a849e52562a67ed543d 2c8fcc9a2abb8e1de32054d2ec1fbae8d7fdb0e4 25437bd14f24f4102f8f42cb9b2c47b71861406c 8e9968910e8aa7b9111f99264a00c1146798fadf 4a834e5bfd72a6c968de73728a0d9973545bcf1b f8a5dbe8f2f76db8cbf790df7394f93d1df8a4da e9c66cce09f2c2daa7761aa4ffc19a271f91abf4 b7674330f6791d5d529990eeb51f372ed7472e39 ac69cfcdc28a5d3bcf5bfcde5a61fa96280f725f 228eb7e3d4fd55b59ba4bcd7d7e58d25a8073bc2 3368bf51083815a4a2d794771732e6c68e59d435 09722e3561fd6975869a0eb7820106119d7b7986 f8c77b02a81f25e3f73574b343a582d8fd204665 3523ab8fda444baaf33283c8c14e296bbded9015 dc4301ffc076a930de86cd51d21ad7f13ac44195 ea53145156c3c7eb50c725f44591b4e7c57167fc 73ec7b7500dc55908c6058d774d4e8b1e95ccfa1 9fc551bc5f505c1d3b73cb3d7c315794d90d2f1f 9bed87e6e60a86bab5ee9a3cbfc3ccd6ba13180b 36ffe6b772673c4f5575296aec85dacae8d9c209 57adc6448f2e71d82fa60294ea097c806d1eb967 923e80c891151a87dcd3a98da515e8c0d41efdeb 1f02e9a7a94c92b47c644ee12d603b79505f824c ae43dcd878abad5db3ad676cac91b54774240f17 ada9dd887d6919b66946544634826f7c2c3e1b48 784f2dc554019ff7779e48977939bf93c922b4a5 89e854bbe7a7b47cb1c2ec01fe12c68bfa9ce6f2 2e00fda57c0f3c4c6e45776c4c01137ae8d8e484 15a0378edbc4833e422c62b24e6a0c08bcc3407f b334e3eb459afc7f1e158a42d0f3e63dab812ad2 7ceac754b7d727c9910614e61307a7ba24263875 59fd08b17937d60efadd29f4c0d0e73fd4695128 00f5969c543978e0512cbe28b8a31a01f683099f 0a9d3329494e84277df34f546298dac727a28071 6c675a72e8486931425d555c6fc4a652a5a15f16 5aef653842d08eacbe01ee42da83119c239bf498 e4be8e2a3d0a1c5fc292bd2c70d793cfdfef6f59 d540694cd8a57bf97b46cdf7588597f21086f10c 96bee07167bd4bc08648e9ea995393bfb7ba5db4 9a1dfac535d3f3ba057767005952b8ae2e624f61 c49e7fe3b3ace35b3168bdf357181a375a0b243d dc3ea2e61b484009bd19cff675640baeaa644d75 0f02a5cae6b38d5e745ef0cb0f9030cabb48180d 89e5256a58431346c8175711304088734e5d9933 6d0f2ab2945740c4769279483acb6e84db559cd1 a982e8b95785b1a7754d0cc52e8b6914a290810d 9c54a9a51aaaff6ccaf4a93e927faae5e5072b30 6dd6bdd1796c853e779dbf8600ff556999a8415a 39efce0abc5d23b40bf58ed64adec8213a511373 a7dd1e6e95d9027378449635f8958c648315a6ca f2dcf439386a63561d009e82e808f51ec47b0c83 2c2c653b06aacaba5003f6af79f472b684624362 d0f4715fd0e30c5253af6490af3b3cc280bc41b5 25d9dad1fbea2f3778d6594cdf72de1c836b9e70 cbad73874c7c10b1af6782eeac6cb571e17abfc5 c320d4a248e3117476d946f913211d9c627b7e6d 14ed76e257399c8af75193d801bdc4600269af5d b5f66a8fd02ab73383345ff74ea7d97edfb6a349 b7127a4a3ce00800c31f069fdc7ab30340214192 ec5a9ada63486f2efcbc05661e9207f5fea546a2 032088966379dd244eb905ba7233c27291cefdbd 70792c241b25a69e0f8a3363719afd2d5dacac3e 059cbf270070456aadd40dd3cfad50a5440b2fad 7e3c137222899f17aa95d7d4ffcf1bf8a37d9389 ffdee402262298a1171b33138810a842f828dd17 d11c072cb3dc17f894c81d84199e1b090f0bf1fc 8002a6bd6b3d8ec78016fad88396e09004874d57 976e62466f222b12effbb457ed3e34942a13de3e 5399cb6991f86cbd0cca15f83946dd2cd402a523 2b3ea873a2d54a2f9f7bab1263618a2317f5c851 e2fd2f6eace7c83ea3e8eb549fbf888a4e7188a6 b00f757fc6b3f5fdb61810a706417a697fd513fd eca88d22f0f26505be6c730f4d4f159a519faf41 6a7922104e9b2d03990f213a7d0a2dcf45192bfc a1c20cdc0e7ce90f79a6c80860e905974051f4d8 18450e8a59c204d219dbf56754e9e88a461028a4 da05b45bcf3120fdf80da030ea9984e2e1666006 394228bb1ba5fef377f536c165dfa827af2c5b84 f915e5f2088292f78a763dadf0bb863693acefa3 a90545cab5a482d824ef2fd56a05b24aeeb06c38 ea7d701560c1991cf3a465e5a437f1a00f480540 d72c7945b2747fc0baf13053f443e3e8a40a90c0 21e5891b54d9616e6d69fb240dc15f6d334bbcb3 b5d9eb69875519244a552e516626650c5eddace1 00f80b8bc96560984b0ffc2ed37de1fdb750b002 69d74ec49ded1c9cbec563b809d72c7371c613a2 adcea73374d7f05aecbb07b3ad104dcafb2b8e43 0b4ae9dc049dc65c3e329346cf89b1453e92bcbc 5dc2759611931f1daae10942908d67505d616304 4fcd17e5158699e6aab4f0ffe7b7f8922b4dc733 2aed76a38851a4737988ae83004a8eafdafda712 2b6026e2d5d6e7252dc9a90de746e27d9b53cec2 55f39d4a1e6fe952f88385b38e4b2edc85695231 7889a6075c20b066182af69cf688d07b51cc626a 6f0109ef9f5630d294c2fd3026e65e8b8886d4ae d6bdf17a9476026467fcb3bc787aa3096cc54fd6 218e2b96a05b91647209ae045f856233a1ae29c8 edba53b871b99fe97170f753afb7b0877b47a964 ef5ba0055e5fe8534fdbd1c830aa02ac71b803d0 f0d9635c2ea4c2fe7a15b990d1db6f1722a6c5c8 b18fa17dfcbc12c8183ec70278bb16f1bad39626 7feca35ffb42f8b0a94f1060d0bd7438a376845e b794e5674eb72ddec2f47be08263c4d6da1bee34 8b61c1761bba5d47cb1a8ec8fc97f676b8970495 63c4304aa72c9db11042a7f43f277f1807e48333 4d1588fbf504038048e255fd1b5b160a56a1ff12 b3f6ae40b57d6c84528f5f499db3f285926abadd d79da881b0854f3590b83edbb37621be8f2a7ec4 69ae92e1e62c16f82780697534d117c9bfb7fb16 038e4435efc4c6d4c7a6e2bb75ea00673852548b ea8031a9bbc9820816aadfc79230e5d920554d44 21037f05639b4fdc9bf5406023fa1455fd9d6b2d 74114498351888210b4755632ce5b6418e12d6d1 ec67cf108e4b8bd0cf5d4dad53b926b3bcbb92a9 8492c6c7336c3dba7511046b363c558fdbc7d16c 8055a458d9ebfaed4b1ed1521711b406c470cee2 ceba8489ac7d4747b3560437266c8a764cb14fee 37454ea46b0135ae340617f4821d5fde5aea94ef f561740931d01673e809197f4e111238750ff105 999288961d4a998d9162670adbd26c33e7134a02 3650628c11720d612d76944067d6c7d64a1b39da 8eaf214617cffd637209699c8a524220b2ebb4ad 6cadf78370b844ee1885475a76c49b3c0ad436ca a9362b47fdb8e5f0c6724f8de8ec1f3bbecc5253 8386ce7745606241acd0689a13bde8117dbd6acc efe0ad3d3947f79d530a66a2d376f34b6a11581a 202b7bd1f3d77ad3016a249d3f65fead94b4ef7b 14ae18d415926bf91fa0efc59e4d266fefffd6c7 b3d24ba93b26308fafeb6c243472ad6dbe9c5e97 2090e1b61de272e50bdf6c54c8ed47e692a6f0d1 62e441e49027d69e23dea65a993d617957192aca 2b27a9079d0b82eaf1717a3bb4d203d054ad57f9 469c3e73536485c8fe00bb8dc1393921db49b59c afdc4e994c2261e74a549248c4b1ad777a5a6f48 f44e2a09e62a091f25646ccb7d76120c51e6742d 840d7d6b14038d5a1c48bf91d5add31dbfb89668 ba879a5f5b239c43ec9a61567f3775664cddb3d1 ec68f80be249d4801a326e3aa2ee1ba8cb8d1167 eaba462cbdbedc9c75c9b554b91eb546361a7e6c ed24a207e21288708dbbadcfac620a71045e82fd 3f16ddfcedf1437b94a7bbfc97f479009a26c6f7 47e9ba762b994c423e1a9018d2654f3abafbda50 8a34c29c9828619167d600f8ce99175ddc601090 c179384f6b4ca3f85e641b1e3e00e9c84f010667 302b6bb3b7ef8bea75ed8e872d8bee4138c8ab6d 46cc0e293a313d4058948e9039e3a9a00c9b6bc7 a13bbfd297117edb742e5bb5990ff2ca39ae715d 94f08a2a115a809ac0caeacd44de2796dc778b26 d5ab574933234205464015d3e7a4851de24e17cf 8e74fd0fd753a19dc3fb20769ef79be0f41303fe 770be891e060a8538a1cd1b7d8424cb85cc835fe 12a9adb05f3d1e347c4e73545593b9830c7cfc15 6b8a8e288d9a406abb540269c15016390704a041 19589f03f91bde04ca93bbc5fb2a4533c5eb161f 88ebda5c47d653656343b77acf38f17cddb5bb65 75011ad6b570548d5f8c027d9f36d48579945f75 2b2524ca7f4046a3b895e5878c7535bc45743d79 c1bc26d472d38b635451e5dcd50e358055757554 8a4bb9e82063619c6e3f43bf0a64b06e109cc4f5 40e2dc9e689b27789990355839c148f58e60c16a 692e9f30130c0ff43f49f0bc45ac5a0daef9ad41 1d0d088371f0fa85b749369df24c7ec0ea6207c7 161f09ff448b4d217649bd721900d43381f3f6ec 2dbe0a788a9dea17abb2ac8c2958c9f5917b96c8 10a22835e910bef2fa763565baf5d0925e51d100 3c28ac007b073d654ab4624aff5e4c64c42d25a9 7bcd7f1a630fc62aeaf54994ffe3cde31fb283a3 18c7375afec817b51963dd0c3b8de313b9e9bd42 b6f540dadd55776a103aefd5def182e8832202a9 d3e9ecd28d5f6a547ba7e2419470c77cadb6955e 7b2c3b730c6c30d30ebe415a76d5aea7f4f4d32b f64a7f92747f5bbfc00c576d38edb7193e1c3bc1 237bcdd0afd8ab7d13a17783a6af6a0bcf77229f 83ae4c63218ce2d0da47aacd971a735cea29a11b 5d9454d69dce8347bd59f99779df0f1b8c7566c2 51fe2ffc7e4761c06b896c82fc625fdff57d686c 49d396ba7aaf4b50ff6352691351063837a18212 5020cbae9ca63e7386d78e7259ce73e8dd7773c7 dda87d03bd7e514059819a23af40989db855cc38 933fc4d5f48d81a48d8457ca67451e0d6395fca2 7ff5c5e8d82f73752484b9beba310839afec3bf5 c964271cbda83a66cba050e8582934e177e78773 39aaed9ce72aa1ec4438054d86f9f4d1abfa910d 3047688c5bb8e53f155f62de3c5fc49064e92f55 a7942007265e81307c94597ceec121ca699852da 614177f474693f5553016156b7343ea2ad88a0b1 08631cac3d9860d26b7a8b7c090365ff21ef8a03 df4a6f53c7ccf57e577bd4f6c27d7ba015e1aa1d 42f22fb2a303025afe3832305bae48777eb7003f 31c12e22ea4a84a5901c9f1862d2e7f682a0b364 1d6161ddd05669ca72b9787d3a3385c3214c71bf e5e1f8e2e32c8caf9c23b6ca01eb528899926960 65c1cd326fa53671d44f5a20790d1c4970695f84 bb2f51d45b68b43959f74beaf0e55c51c549fe3d 998b87276fb7c55c6e58e606c0501137d3abd99d 88951afddaa674841f54de867c88e9ee40460dc8 57f923b4bd8926f0e44d9f4a1e770ae40b5a844a a4a82537ab4af1e3dde8c0643099406d7d580848 53eaf5ebf31e5e63c8719825dac6abeb949bee0a 41758a99f7a83bf61cb0ec2577a6fb9f3e3ff0a1 cb1614214d45fc8532a7d548e7bd79b960e56944 8a9eaa02dd866c6870e14aa03a11634efbd85102 35771bfcda68fe1f107c092442ebdbff6a8c250b 9da4b31b2f19e135dfbd1060cd6cc4698583e451 bd8ed99a8c42cf1d6cb779da5fcc8371d8fd8767 ffa156588e9192a64251db120709358f27b023fe 68566814048e439154c25397be04da9d26de34ad 00b48a10c4bf9018c239ae23af4a59cd0c6a9e7e 237aff91c3375407e89988a825c03d1f54bb26e6 d29c4e1e5d0bd7b82f1571671ace20af9de50130 f706cf3623760e52691d2500f99106d697fcc95d c69bb0f66487625c716f833528646b977ee13d89 b1c8de2a553fd011ee903512d7907e0ddd206bfa d844efb95fe92556af18bbc8b29c45710487d9fc 71a74f36769574a6f8b8f7092056657705175bb1 67af848f7b6d0a9d30b49561f5588f1c54c661c5 4323fe4d8f2f4833ebb71b45a9efaad460bb404f 1b0af2a39a8cf45f456d7c43907c7009ebcc42c9 d63e6a9254610b9e16b4c6c4ca9feb462700c9c1 061e8788232057716aaea5d8459c6ceafc4d599a b7205571f70da64ff5746ea1edd100cf7f071717 967a4c5c9315c86c3f58fda22f986efe558c3cf0 7895409496eb2485bcf7bbdc99b13c5e9e2ee8a0 83e757965446ef1316b9211e7f0df9fd5b103865 20bd220d49f057a72c2feeaeb821189d11f52eff ea766f2c2c2619d8d63c4ecca6310f120fcd2046 02d5abca5f98cb6e9d65a6c2f3de8959016bb1ef 52a9341747577addc1be31683980732280b422de 923dbcce925b9b46c75b829396b0942c1b2494a0 8930ebaf45c2d1fd2c0bb8eca0ee49ed5a537e57 df9acfba962f679240f413b9c78e66448bffec57 ea3de4611b446a0139578cdcbc757ea5df3b0870 5a1f82fc641d515df968140f6555122f7e7c7a56 7f82fe7ab442736386225cd4f6a159a6ace38776 83354d5917871ce23872d8603023e24d3a8d644b 995db0a92a36de7b1ef0ebb25d62a0d780f91f35 f3406177a234e5958673caaf9c6768d1a7edc258 c2872e7d3e26fbeb41a503dda620f7e5e18d861b 138eb24d4deefd9cd69b1444b67121d0da750e39 d8d81f21e33d54e45d6142171bcfbbcfbd0dd278 b044049bf9853de8957d75fdd6eb1eb4f5332b87 a63092d20c7d547c1cab93bae5c0a175e35257b0 85f4a97b4d588deae56b92752406c6fd2aaaaba1 532fb1e7406aaff5b6cb7343fe682dd009bf2aa1 427891a02d697618a7a43c4851c28aab7c99d99f c95de066bad7aedc14651c2407ef23b8b9e3e57b 3095db053d42ffdd7c9876af002c32e8aaf8eba3 5eee146bc5b35805763e191b97bbc24f3b231a31 b540cadc6157c176d700edeb60d1f39422b40b18 c712e26684aed3ccf430e8468d724d7ab7d5daf7 b2797cafa6dda966614a4db3da4fafc3cbd4e8f4 cbe6defd3207f2f11ecf8269cc67dec97fe98400 74dac97da95db43648af2a89f4af0d8d8ce01474 fef6d8a0610cc941fc2be7349ec77d48cb0e1875 d02fe685497761715a1f7307fea2ee00f6d0ab2b 69e8f84117065ca070b61cb4c70bfa122bcdfefd 3e683027994219ca829c837ca9722a974d9a952a 3e631eaf4bebfd928ceef82ad69bbba272a08ec3 ea3e218bf69ca298d0be29892a6fe378e5a3900b fc13acdb63a2d988c156adece5f78a651eed77cd dc13b818d7996922c2ba3bbdedad53ae3b7c4bab 9c6b6d6bb23f89bb7b07a9fdbc4b09ab0413a515 40c85733f3d96b700b1846ea7d059ec7d2ff24be ec2f2d2a8ea39dc71d6b126804d00d0dc284339e 3a59eeeafd7f9860b374fc441a491a9514a58297 80556970aa5436de39c65bdc010acebd88899e73 bb19f4b437578beb519a1e12ed0e9e23aeef331c 96f51761cdd62505b676ae235c5785831a2e5427 52bfa28bbdf5e8aff5153bb53e1494e3da8838cf c6b1e19d4d6f1952bb4b690b877213c76343c54e 501ed3289e0119b84e57fd01cba959e67caf5f78 d91cf1d47edf697c5aeb0cc77ebd61bcb7391872 fab0ae72dc8d1444d2610e914c3015009dca1ee7 328a554c31cc071fe17dd91ff71521bb6aa1c774 42575195facd61b864b8ffe4384a1b2f3d4f7648 aa03be728bd8c525b29789638c0f0de8a27d28ec 88276b5ae9b5385bf7a1c40f6b03045d90ff2893 c1f83283458b2db3094b382bae3fdddf542ed207 80d8cda2a2cfe0533751416cae24e35c8091faa3 34f05475294f9e2d6e37c669dfa3101b87f0d712 8d788d025975834c0edeefda5a7e0ecd404c3a85 569f4b11d6acddceedb73f0444df7b9366a43191 db57d544ae4396bbbd5ac97cfe12cad7c8db69ed 54f57737dbbd6e7e8e342bb2d26b9a6d7724506e 963a48f4f18d1b1c6b339c19e908dba506f8d6a0 00860a23f69ebc01287948258177db4f7c51e0cd 3f38b178a7200342ab65bda82735a8cd21dd222c b626ce024fed5a5a05f5d13d60506440c9a09e38 ddb9800e7a6063d3532b384cc4fc9da75b2ad6b7 236cef11d6ec692198260395a7d1c0697ab2ebab 07b4de8eede971c8497031ea4bbb1b9e8a913e17 7d923d56908043faeea3e6039f47a2ff0669a94b 174ef8e7c12c2dc7b59fe3eaccfa5636b11f31bc 79fd1dd7b0ac8791b6e65297aadf2bbd6071bfa6 4ff546b54e262ce636a0b912a5f23978b618f31e aabad0ac48bf5144819c307c91ff0f5ea14ba068 037f52d0e372af918a059670fc1dcb5dd258677c c823ce7b41861a16bf99e6085f99cf46f984ccc6 2fb4a33513b6a241c3816a99053d44e406f81ba7 b00203cb368b2fc1a5d81aef43e05047d4e1a975 b95b42140d632d54819d4125f627aac237870311 e0dc45c876c09da462d9081ce6781f009d0f95c5 a8003163ae21216a21ad5a1f3081c45f138dd231 979ed86f2d79675d4bfa034d820beccc0f17189c 518cbc7255fa90493163c1f16bbe43f5a12d4b5c 06c307144df18e50b17bdd0e73853d3b42c40012 d863c9bbb8390debebbff723d142731878a03a08 c759a29dcd971f8293137ff314d4c0aabcc0d5d3 ee68f958082ed7761f4e5dd60bfc56c46bc21682 91b63e4401fd674cbc14db9a79e7836acebcfab2 ac91f9797d8fef487bb713c59fa0f8fde2faf172 75cdac450be210261a2a9570fd1cf4b0171e9f60 b243c261e6fe3baacf1b55df0188d70efebcf2ae 1f4ee0b145857933fa511747fc4a101014b8fd4d a5b159b73ae51059fe01d309444e9dc840ba253d 04605216776095d53b1fd36d9a0b8097e403be9e f5ce7643d85e9a9de60d5e05406dc4762500e382 fb3633bd67220e49e170b93688eb90a1c6e09cbf 5158bd0f780727d5bb7af4f24601c7734a368bc3 60c2cd3e8e598d3dac95bd9a940240b2d3c6d767 73fa2bd272141db28c62065f2da012daf5322ef6 1d5dc04bfeb696da99827b26230b25df84f17c56 0d25e1d7db3668a7ed3093700c933ad100a66579 aceb646d45aa08137a41444e73ccfbd736f2a74e f5321cc6e9ab6878d0ec63adfc4d3d1dec168a5e 3e60cde25032ff2389a1ceb0095472395f092bba 19c6a49431467cc57fca16f77eedc72aeb6aa3ad ad20ab84060774c29f80ff1b769a26679fff2b19 c2b21c8c502da2d55bdb0f4372f245fbcdc5ff94 20038d60a029f911942ea62b4e08a975882b0dad 8f925a689013963b0026db84031c4d392cb8f777 72600c0e2f662c575d9e413590f444d061f07e9b 02703ac9c46b6d677264a339d19ff9c7123dc9d9 6ded820dc52da2039ee7bc633346afcd8a3206e1 +Branch:master +HEAD:2981c3c1b2f416c222bb087ae5c3f24045770439 +PREV_HASH:18ae0f56fd467032d969cee962b745245d9f3a01354256441c87006e65f649b879e145892a7bcff12d7d509e73d534a65e62907bc9e3703228cb03650d7a11a8 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQIcBAEBCAAGBQJaBMmoAAoJEJ6H4TNx65aE4PMQAJhOPh/ZbAur6hvCQjztgSLa +laLyCUvUX1bcnMgRXIYK+E50IAQ9YLE1BVUrVnPhHgGNAAybxiCLv/iHXwHeVpJc +uBStRoKk4c/vFcFlb6LipVQkqRaBS7+syQWlOsHr6AAPHQ5pfFwg4LKXlIpkpre/ +sCeSB4CNoWmrgxha3YXOU7bEfuWFqnxHDc/rfLNhyT1MuhRWjNuq0adgazibi7iS +18jpi3F1jz/Kj9JVUiid9GZQmTvW1luUVpPhYUPccHxFP8LqhlbKLvPyILtNCSBb +Q5UVVturrn+MYRwGeQPym8RSorDBykYklF0xCgMdhuCZY0VRMFL1o1K8z9RfLVcm +I8XqKP7TV/k9ix2o0m4NlbTpU37yPjpLlgFv6eZhR+PSJ2yT9W/6uNBMumJEbZGr +O9H97M6MZlZeGj8UKUP0LrLTro3Zb8ANxUsaAwZc49HRS6/uX5srfPjIA9LfwMn3 +VzpZBo0QySoNEdBYte3JqiIyw/juXM0q/rLdH4w2+7RMHQRItYJX67uLD1u/+8/7 +dndvMQ0jrPjXfgcSo9yyxpuroDQcM+yz5uD3GUBqAYe1F8JOZ3OaliFGHcN5+KKh +EgnCvl3VQQv5zOrEGbvw05bwWA9H3prr5592VvCndqyTbHz2lI+vmPtZ/mGSAfO5 +2DZrM0jNAH/L68PAkmVM +=k8oc +-----END PGP SIGNATURE----- diff --git a/CANReader/CANReaderNode.cpp b/CANReader/CANReaderNode.cpp deleted file mode 100644 index 983284e..0000000 --- a/CANReader/CANReaderNode.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example CANReaderNode.cpp - * - * PolySync CAN API reader Example. - * - * Shows how to use the CAN API to read CAN frames. - * - * The example uses the standard PolySync node template and state machine. - * Send the SIGINT (control-C on the keyboard) signal to the node/process to do a graceful shutdown. - * - */ - -#include -#include - -#include -#include -#include -#include - - -class CANReaderNode : public polysync::Node -{ - -public: - - CANReaderNode( uint channelID ) - : - _channel( channelID, _flags ) - { - // empty - } - - virtual ~CANReaderNode() = default; - -protected: - - /** - * This function is triggered once when the node has initialized in the - * PolySync context. - */ - virtual void initStateEvent() - { - std::cout << "CANReaderNode::initStateEvent()" << std::endl; - - try - { - _channel.setBitRate( _bitRate ); - - _channel.goOnBus(); - } - catch( polysync::DTCException & exception ) - { - // If interaction with the channel fails, print why and trigger - // errorStateEvent() - std::cout << exception.what() << std::endl; - - activateFault( exception.getDtc(), NODE_STATE_ERROR ); - } - } - - /** - * Called repeatedly while node is in an operational state. For this - * example, we will read CAN data and print useful information. - */ - virtual void okStateEvent() - { - try - { - // Read data from the device, timeout after one second. - _channel.read( 1000000 ); - - // Output CAN frame data. - std::cout << "CAN frame - ID: 0x" - << _channel.getInputFrameId() - << std::endl; - - std::cout << "DLC: " - << _channel.getInputFramePayloadSize() - << std::endl << std::endl; - } - catch( polysync::DTCException & exception ) - { - auto errorCode = exception.getDtc(); - - if( exception.getDtc() != DTC_UNAVAILABLE ) - { - if( errorCode == DTC_INTR ) - { - std::cout << "CAN read was interrupted, application most " - << "likely received SIGINT (ctrl-c)." - << std::endl; - - disconnectPolySync(); - - return; - } - - std::cout << exception.what() << std::endl; - - // Activate a fault state for this node. The NODE_STATE_ERROR - // will trigger call to errorStateEvent. - activateFault( exception.getDtc(), NODE_STATE_ERROR ); - } - else - { - std::cout << "Device unavailable. " << std::endl; - } - } - - // Sleep for one millisecond - polysync::sleepMicro( 1000 ); - } - - /** - * If exceptions occurred in @ref okStateEvent or @ref initStateEvent, we - * disconnect, which triggers @ref releaseStateEvent and allows for graceful - * exit. - */ - virtual void errorStateEvent() - { - std::cout << "CANReaderNode::errorStateEvent()" << std::endl; - - disconnectPolySync(); - } - - -private: - - polysync::CANChannel _channel; - - uint _flags{ PSYNC_CAN_OPEN_ALLOW_VIRTUAL }; - - ps_datarate_kind _bitRate{ DATARATE_500K }; - -}; - -/** - * Entry point for this example application - * The "connectPolySync" function begins the node's PolySync execution loop. - * - * @param argc - int, the number of parameters on the command-line - * @param argv - char* [], the parsed command-line arguments - * - * @return int - exit code - */ -int main( int argc, char *argv[] ) -{ - // Check for shared memory key argument - if( argc > 1 ) - { - try - { - if( polysync::getChannelCount() > 0 ) - { - CANReaderNode canReader( std::stoul( argv[ 1 ] ) ); - - canReader.setNodeName( "polysync-can-reader-cpp" ); - - canReader.connectPolySync(); - } - else - { - std::cout << "No available CAN channels." << std::endl; - } - } - catch( std::exception & e ) - { - std::cout << "Invalid argument. This example requires valid " - "integer input representing a CAN channel." - << std::endl - << "For example: " - "polysync-can-reader-cpp 1" - << std::endl; - - return 1; - } - } - else - { - std::cout << "Must pass CAN channel argument." << std::endl - << "For example: " - "polysync-can-reader-cpp 1" << std::endl; - - return 1; - } - - return 0; -} diff --git a/CANReader/CMakeLists.txt b/CANReader/CMakeLists.txt deleted file mode 100644 index fc4ec66..0000000 --- a/CANReader/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-can-reader-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( - ${PROJECT_NAME} - CANReaderNode.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/CANReader/README.md b/CANReader/README.md deleted file mode 100644 index 5f05277..0000000 --- a/CANReader/README.md +++ /dev/null @@ -1,32 +0,0 @@ -### CANReader - -Using the PolySync state machine, this example does a simple CAN read in the OK state. -This example also acts as a guide for when you need a node to listen to a CAN channel. - -### Hardware requirements - -- linuxcan-compatible hardware is connected, i.e. a Kvaser Leaf Light - -### Dependencies - -You need to have a CAN channel to run this example, see: [Connecting To A CAN Sensor](https://help.polysync.io/articles/configuration/runtime-node-configuration/connecting-to-a-can-radar-sensor/) - -Packages: libglib2.0-dev - -To install on Ubuntu - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd CANReader -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-can-reader-cpp 1 -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/CANReaderAndPublisher/CANReaderAndPublisher.cpp b/CANReaderAndPublisher/CANReaderAndPublisher.cpp deleted file mode 100644 index 86be0dc..0000000 --- a/CANReaderAndPublisher/CANReaderAndPublisher.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example CANReaderAndPublisher.cpp - * - * PolySync CAN API reader and publisher example. - * - * Shows how to use the CAN API to read CAN frames, and use the Messaging API - * to populate and publish a raw CAN frame to the bus. - * - * The example uses the standard PolySync node template and state machine. - * Send the SIGINT (control-C on the keyboard) signal to the node/process to do a graceful shutdown. - * - */ - -#include -#include - -#include -#include -#include -#include - -class CANReaderAndPublisher : public polysync::Node -{ - -public: - - CANReaderAndPublisher( uint channelID ) - : - _channel( channelID, _flags ) - { - // empty - } - - virtual ~CANReaderAndPublisher() = default; - - - polysync::datamodel::CanFrameMessage buildCanFrameMessage() - { - // Read data from the device, timeout after one second. - auto payload = _channel.read( 1000000 ); - - std::vector < uchar > payloadVector; - - payloadVector.assign( payload.begin(), payload.end() ); - - // Create a local CAN Frame message that we can pack with data - polysync::datamodel::CanFrameMessage canFrame( *this ); - - canFrame.setDataBuffer( payloadVector ); - - // The message timestamp represents the first instance when the data - // was received by PolySync - canFrame.setTimestamp( _channel.getInputFrameHardwareTimestamp() ); - - return canFrame; - } - - void printData( std::vector < uchar > payloadVector ) - { - // Output CAN frame data. - std::cout << "CAN frame - ID: 0x" - << _channel.getInputFrameId() - << std::endl; - - std::cout << "DLC: " - << _channel.getInputFramePayloadSize() - << std::endl << std::endl; - - std::cout << "Data Payload" << std::endl; - - for( auto currentFrame : payloadVector ) - { - std::cout << "\t" << (short) currentFrame << std::endl; - } - } - -protected: - - /** - * This function is triggered once when the node has initialized in the - * PolySync context. - */ - virtual void initStateEvent() - { - try - { - _channel.setBitRate( _bitRate ); - - _channel.goOnBus(); - } - catch( polysync::DTCException & exception ) - { - // If interaction with the channel fails, print why and trigger - // errorStateEvent() - std::cout << exception.what() << std::endl; - - activateFault( exception.getDtc(), NODE_STATE_ERROR ); - } - } - - /** - * Called repeatedly while node is in an operational state. For this - * example, we will read CAN data, populate a PolySync CAN frame message - * with the incoming data, and print useful information for each frame. - */ - virtual void okStateEvent() - { - try - { - auto canFrame = buildCanFrameMessage(); - printData( canFrame.getDataBuffer() ); - - // The header timestamp represents when this message was - // published to the bus by the producer - canFrame.setHeaderTimestamp( polysync::getTimestamp() ); - - canFrame.publish(); - } - catch( polysync::DTCException & exception ) - { - auto errorCode = exception.getDtc(); - - if( exception.getDtc() != DTC_UNAVAILABLE ) - { - if( errorCode == DTC_INTR ) - { - std::cout << "CAN read was interrupted, application most " - << "likely received SIGINT (ctrl-c)." - << std::endl; - - disconnectPolySync(); - - return; - } - - std::cout << exception.what() << std::endl; - - // Activate a fault state for this node. The NODE_STATE_ERROR - // will trigger call to errorStateEvent. - activateFault( exception.getDtc(), NODE_STATE_ERROR ); - } - else - { - std::cout << "Device unavailable. " << std::endl; - } - } - - // Sleep for one millisecond - polysync::sleepMicro( 1000 ); - } - - /** - * If exceptions occurred in @ref okStateEvent or @ref initStateEvent, we - * disconnect, which triggers @ref releaseStateEvent and allows for graceful - * exit. - */ - virtual void errorStateEvent() - { - std::cout << "CANReaderNode::errorStateEvent()" << std::endl; - - disconnectPolySync(); - } - - -private: - - polysync::CANChannel _channel; - - uint _flags{ PSYNC_CAN_OPEN_ALLOW_VIRTUAL }; - - ps_datarate_kind _bitRate{ DATARATE_500K }; - -}; - -/** - * Entry point for this example application - * The "connectPolySync" function begins the node's PolySync execution loop. - * - * @param argc - int, the number of parameters on the command-line - * @param argv - char* [], the parsed command-line arguments - * - * @return int - exit code - */ -int main( int argc, char *argv[] ) -{ - // Check for shared memory key argument - if( argc > 1 ) - { - try - { - if( polysync::getChannelCount() > 0 ) - { - CANReaderAndPublisher canReader( std::stoul( argv[ 1 ] ) ); - - canReader.setNodeName( "polysync-can-reader-cpp" ); - - canReader.connectPolySync(); - } - else - { - std::cout << "No available CAN channels." << std::endl; - } - } - catch( std::exception & e ) - { - std::cout << "Invalid argument. This example requires valid " - "integer input representing a CAN channel." - << std::endl - << "For example: " - "polysync-can-reader-cpp 1" - << std::endl; - - return 1; - } - } - else - { - std::cout << "Must pass CAN channel argument." << std::endl - << "For example: " - "polysync-can-reader-cpp 1" << std::endl; - - return 1; - } - - return 0; -} diff --git a/CANReaderAndPublisher/CMakeLists.txt b/CANReaderAndPublisher/CMakeLists.txt deleted file mode 100644 index c6fad5f..0000000 --- a/CANReaderAndPublisher/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-can-reader-and-publisher-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( - ${PROJECT_NAME} - CANReaderAndPublisher.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/CANReaderAndPublisher/README.md b/CANReaderAndPublisher/README.md deleted file mode 100644 index 69f817f..0000000 --- a/CANReaderAndPublisher/README.md +++ /dev/null @@ -1,32 +0,0 @@ -### CANReaderAndPublisher - -This example also acts as a guide for when you need a node to read and publish data on a CAN channel. -Using the PolySync state machine, this example does a simple CAN read and publishes each CAN frame received to the PolySync bus as a `ps_can_frame_msg`. - -### Hardware requirements - -- linuxcan-compatible hardware is connected, i.e. a Kvaser Leaf Light - -### Dependencies - -You need to have a CAN channel to run this example, see: [Connecting To A CAN Sensor](https://help.polysync.io/articles/configuration/runtime-node-configuration/connecting-to-a-can-radar-sensor/) - -Packages: libglib2.0-dev - -To install on Ubuntu - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd CANReaderAndPublisher -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-can-reader-and-publisher-cpp 1 -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/CANWriter/CANWriterNode.cpp b/CANWriter/CANWriterNode.cpp deleted file mode 100644 index 0c7f82f..0000000 --- a/CANWriter/CANWriterNode.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example CANWriterNode.cpp - * - * PolySync CAN API writer Example. - * - * Shows how to use the CAN API to write CAN frames. - * - * The example uses the standard PolySync node template and state machine. - * Send the SIGINT (control-C on the keyboard) signal to the node/process to do a graceful shutdown. - * - */ - -#include -#include - -#include -#include -#include -#include - -class CANWriterNode : public polysync::Node -{ - -public: - - /** - * @brief CANReaderNode constructor - * Open @ref _channel - */ - CANWriterNode( uint channelID ) - : - _flags( PSYNC_CAN_OPEN_ALLOW_VIRTUAL ), - _bitRate( DATARATE_500K ), - _channel( channelID, _flags ) - { - // empty - } - - virtual ~CANWriterNode() = default; - -protected: - - /** - * This function is triggered once when the node has initialized in the - * PolySync context. - */ - virtual void initStateEvent() - { - std::cout << "CANWriterNode::initStateEvent()" << std::endl; - - try - { - _channel.setBitRate( _bitRate ); - - _channel.goOnBus(); - } - catch( polysync::DTCException & exception ) - { - // If interaction with the channel fails, print why and trigger - // errorStateEvent - std::cout << exception.what() << std::endl; - - activateFault( exception.getDtc(), NODE_STATE_ERROR ); - } - } - - /** - * Called repeatedly while node is in an operational state. For this - * example, 1 byte is written to the CAN channel passed in. - */ - virtual void okStateEvent() - { - try - { - _channel.setOutputFrameId( 0x456 ); - - _channel.setOutputFramePayloadSize( 1 ); - - std::cout << "Writing CAN frame - ID: " - << _channel.getOutputFrameId() - << " - Output payload size: " - << _channel.getOutputFramePayloadSize() - << std::endl; - - std::array< uchar, 8 > outputData{ 0 }; - - outputData[ 0 ] = 0xFF; - - _channel.write( outputData ); - - polysync::sleepMicro( 100000 ); - } - catch( polysync::DTCException & exception ) - { - std::cout << exception.what() << std::endl; - - // Activate a fault state for this node. The NODE_STATE_ERROR - // will trigger call to errorStateEvent. - activateFault( exception.getDtc(), NODE_STATE_ERROR ); - } - - } - - /** - * @brief errorStateEvent - * If exceptions occurred in @ref okStateEvent or @ref initStateEvent, we - * disconnect, which triggers @ref releaseStateEvent and allows for graceful - * exit. - */ - virtual void errorStateEvent() - { - std::cout << "CANWriterNode::errorStateEvent()" << std::endl; - - disconnectPolySync(); - } - -private: - - uint _flags; - - ps_datarate_kind _bitRate; - - polysync::CANChannel _channel; - -}; - -/** - * @brief main - * - * Entry point for this example application - * The "connectPolySync" function begins the node's PolySync execution loop. - * - * @param argc - int, the number of parameters on the command-line - * @param argv - char* [], the parsed command-line arguments - * - * @return int - exit code - */ -int main( int argc, char *argv[] ) -{ - if( argc > 1 ) - { - ulong channel = 0; - - try - { - channel = std::stoul( argv[ 1 ] ); - } - catch( ... ) - { - std::cout << "Invalid argument, example expects an integer " - "representing a CAN channel." << std::endl; - - return 1; - } - - try - { - CANWriterNode canWriter( channel ); - - canWriter.setNodeName( "polysync-can-writer-cpp" ); - - canWriter.connectPolySync(); - } - catch( polysync::DTCException & exception ) - { - std::cout << exception.what() << std::endl; - - std::cout << "Make sure a CAN device is connected to your machine." - << std::endl; - - return 1; - } - } - else - { - std::cout << "Example expects an integer " - "representing a CAN channel." - << std::endl - << "For example: " - << std::endl - << "./polysync-can-writer-cpp 1" - << std::endl; - return 1; - } - - return 0; -} diff --git a/CANWriter/CMakeLists.txt b/CANWriter/CMakeLists.txt deleted file mode 100644 index 065bd3d..0000000 --- a/CANWriter/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-can-writer-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( - ${PROJECT_NAME} - CANWriterNode.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/CANWriter/README.md b/CANWriter/README.md deleted file mode 100644 index e16f045..0000000 --- a/CANWriter/README.md +++ /dev/null @@ -1,32 +0,0 @@ -### CANWriter - -Using the PolySync state machine, this example performs a simple CAN read in the OK state. -This example also acts as a guide for when you need a node to publish data to a CAN channel. - -### Hardware requirements - -- linuxcan-compatible hardware is connected, i.e. a Kvaser Leaf Light - -### Dependencies - -You need to have a CAN channel to run this example, see: [Connecting To A CAN Sensor](https://help.polysync.io/articles/configuration/runtime-node-configuration/connecting-to-a-can-radar-sensor/) - -Packages: libglib2.0-dev - -To install on Ubuntu - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd CANWriter -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-can-writer-cpp 1 -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/CSVExporter/CMakeLists.txt b/CSVExporter/CMakeLists.txt deleted file mode 100644 index 72e7d98..0000000 --- a/CSVExporter/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-csv-export ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - include - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - CSVExport.cpp - SubscriberMap.cpp - Subscriber.cpp -) - -target_link_libraries( ${PROJECT_NAME} - getopt_cpp - ${PSYNC_LIBS} -) diff --git a/CSVExporter/CSVExport.cpp b/CSVExporter/CSVExport.cpp deleted file mode 100644 index 7e56d5e..0000000 --- a/CSVExporter/CSVExport.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "CSVExport.hpp" - -/** - * @brief This function is main which collects arguments passed in and then - * proceeds to open a subscriber application. Each subscriber is a templated - * class with in the SubscriberMap factory constructing one CSV for each - * message topic. The csv files are names by message type name and a common - * timestamp at subscriber spin up. - */ -int main( int argc, char *argv[] ) -{ - //Load in the Subscriber Factory that builds message types from args - SubscriberMap callType; - - Parameters setParameters; - - //Set the arguments passed in from command line and error out if empty - //or missing atleast one message type - if( handleOptions( - {argc, argv}, - &setParameters ) != 0 ) - { - return 1; - } - - if( setParameters.messageType.empty() ) - { - printMissingMessageType(); - - return 0; - } - - //Subscribe to each message type requested by the user - std::vector< std::string >::iterator messageTypeIterator; - std::vector< polysync::DataSubscriber* > subscriberType; - - for( messageTypeIterator = setParameters.messageType.begin(); - messageTypeIterator != setParameters.messageType.end(); - messageTypeIterator++ ) - { - subscriberType.push_back(callType.newType( - *messageTypeIterator ) ); - } - - //Now that all subscribers are up connect with the polysync bus - polysync::Application::getInstance()->connectPolySync(); - - //Once connection has been left cleanup subscriber classes - std::vector< polysync::DataSubscriber* >::iterator subscriberIterator; - - for( subscriberIterator = subscriberType.begin(); - subscriberIterator != subscriberType.end(); - subscriberIterator++ ) - { - delete *subscriberIterator; - } - - return 0; -} - - -int handleOptions( - GetOpt && getOpt, - Parameters * setParameters ) -{ - if( getOpt.getOptions().empty() ) - { - std::cout << "It appears you have not entered any arguments "; - - std::cout << "showing help:\n"; - - printHelp(); - - return 1; - } - - for ( auto option : getOpt.getOptions() ) - { - //Check for message type as this is required - if( option.getOptionString() == "t" ) - { - setParameters->messageType = option.getArguments(); - } - - if( option.getOptionString() == "h" ) - { - printHelp(); - - return 1; - } - - if( option.getOptionString() == "m" ) - { - SubscriberMap messages; - messages.printMessages(); - return 1; - } - } - - return 0; -} - - -void printHelp() -{ - std::cout << "Message Type is a required option all others are optional\n"; - - std::cout << "Options: \n"; - - std::cout << "Flag: Description: Default:\n"; - - std::cout << "-t Message Type\n"; - - std::cout << "-m Print available messages\n"; - - std::cout << "-h Prints help\n"; - - return; -} - - -void printMissingMessageType() -{ - std::cout << "It appears a Message Type was not set, "; - - std::cout << "make sure to set one or more message type(s) with -t.\n"; - - SubscriberMap messages; - messages.printMessages(); - - return; -} - diff --git a/CSVExporter/README.md b/CSVExporter/README.md deleted file mode 100644 index f49c180..0000000 --- a/CSVExporter/README.md +++ /dev/null @@ -1,32 +0,0 @@ -### CSVExporter - -This subscribes to a limited set of message types (below), and writes the incoming data to a CSV file (one CSV file for each message type): - - `ps_platform_motion_msg` - `ps_objects_msg` - `ps_lane_model_msg` - `ps_lidar_points_msg` - `ps_radar_targets_msg` - `ps_traffic_sign_msg` - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd CSVExporter -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-csv-export -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/CSVExporter/Subscriber.cpp b/CSVExporter/Subscriber.cpp deleted file mode 100644 index 5665a87..0000000 --- a/CSVExporter/Subscriber.cpp +++ /dev/null @@ -1,460 +0,0 @@ -#include "Subscriber.hpp" - -template<> -void Subscriber::handleEvents( - std::shared_ptr message ) -{ - if( auto inMessage = polysync::datamodel::getSubclass< - polysync::datamodel::RadarTargetsMessage >( message ) ) - { - std::stringstream repeatStream; - - outputHeaderData( repeatStream, inMessage ); - - //Wrap all output around Targets/Objects so header and sensor descriptor - //data repeats - auto outputTargets = inMessage->getTargets(); - - std::vector< polysync::datamodel::RadarTarget >::iterator - outputTargetsIterator; - - - for( outputTargetsIterator = outputTargets.begin(); - outputTargetsIterator != outputTargets.end(); - outputTargetsIterator++ ) - { - auto outputPositions = outputTargetsIterator->getPosition(); - auto outputSize = outputTargetsIterator->getSize(); - auto outputVelocity = outputTargetsIterator->getVelocity(); - - _outFile - << repeatStream.str() - << outputTargetsIterator->getId() << "," - << outputTargetsIterator->getTimestamp() << "," - << ( uint ) outputTargetsIterator->getNativeTimestampFormat() << "," - << outputTargetsIterator->getNativeTimestampValue() << "," - << outputPositions[ 0 ] << "," - << outputPositions[ 1 ] << "," - << outputPositions[ 2 ] << "," - << outputSize[ 0 ] << "," - << outputSize[ 1 ] << "," - << outputSize[ 2 ] << "," - << outputVelocity[ 0 ] << "," - << outputVelocity[ 1 ] << "," - << outputVelocity[ 2 ] << "," - << outputTargetsIterator->getRangeRate() << "," - << outputTargetsIterator->getTrackStatus() << "," - << outputTargetsIterator->getRangeType() << "," - << outputTargetsIterator->getZoneType() << "," - << outputTargetsIterator->getQuality() << "," - << outputTargetsIterator->getAmplitude() << "," - << outputTargetsIterator->getMagnitude() << "," - << outputTargetsIterator->getAlias() << "," - << outputTargetsIterator->getCrossSection() << "," - << outputTargetsIterator->getScanIndex() << "\n"; - } - } - - return; -} - -template<> -void Subscriber< polysync::datamodel::RadarTargetsMessage >::outputCSVHeader() -{ - _outFile << "HeaderType" << "," - << "HeaderTimestamp" << "," - << "HeaderSrcGuid" << "," - << "SensorDescriptorId" << "," - << "SensorDescriptorType" << "," - << "SensorDescriptorTransformParentId" << "," - << "SensorDescriptorTransformTimestamp" << "," - << "SensorDescriptorTransformStack0Id" << "," - << "SensorDescriptorTransformStack0Timestamp" << "," - << "SensorDescriptorTransformStack0Origin0" << "," - << "SensorDescriptorTransformStack0Origin1" << "," - << "SensorDescriptorTransformStack0Origin2" << "," - << "SensorDescriptorTransformStack0Orientation0" << "," - << "SensorDescriptorTransformStack0Orientation1" << "," - << "SensorDescriptorTransformStack0Orientation2" << "," - << "SensorDescriptorTransformStack0Orientation3" << "," - << "RadarTargetId" << "," - << "RadarTargetTimestamp" << "," - << "RadarTargetNativeTimestampFormat" << "," - << "RadarTargetNativeTimestampValue" << "," - << "RadarTargetPosition0" << "," - << "RadarTargetPosition1" << "," - << "RadarTargetPosition2" << "," - << "RadarTargetSize0" << "," - << "RadarTargetSize1" << "," - << "RadarTargetSize2" << "," - << "RadarTargetVelocity0" << "," - << "RadarTargetVelocity1" << "," - << "RadarTargetVelocity2" << "," - << "RadarTargetRangeRate" << "," - << "RadarTargetTrackStatus" << "," - << "RadarTargetRangeType" << "," - << "RadarTargetZoneType" << "," - << "RadarTargetQuality" << "," - << "RadarTargetAmplitude" << "," - << "RadarTargetMagnitude" << "," - << "RadarTargetAlias" << "," - << "RadarTargetCrossSection" << "," - << "RadarTargetScanIndex" << "\n"; - - return; -} - -template<> -void Subscriber< polysync::datamodel::LidarPointsMessage >::handleEvents( - std::shared_ptr message ) -{ - if( auto inMessage = - polysync::datamodel::getSubclass< - polysync::datamodel::LidarPointsMessage >( message ) ) - { - std::stringstream repeatStream; - - outputHeaderData( repeatStream, inMessage ); - - repeatStream - << inMessage->getStartTimestamp() << "," - << inMessage->getEndTimestamp() << "," - << ( uint ) inMessage->getNativeStartTimestampFormat() << "," - << inMessage->getNativeStartTimestampValue() << ","; - - //Wrap all output around Targets/Objects so header and sensor descriptor - //data repeats - auto outputPoints = inMessage->getPoints(); - - std::vector::iterator - outputPointsIterator; - - - for( outputPointsIterator = outputPoints.begin(); - outputPointsIterator != outputPoints.end(); - outputPointsIterator++ ) - { - auto position = outputPointsIterator->getPosition(); - - //Output each target - if( _outFile.good() ) - { - _outFile - << repeatStream.str() - << position[ 0 ] << "," - << position[ 1 ] << "," - << position[ 2 ] << "," - << ( uint ) outputPointsIterator->getIntensity() - << "\n"; - } - else - { - std::cout << "Error writing to file stream..." << std::endl; - } - } - } - - return; -} - -template<> -void Subscriber< polysync::datamodel::LidarPointsMessage >::outputCSVHeader() -{ - _outFile << "HeaderType" << "," - << "HeaderTimestamp" << "," - << "HeaderSrcGuid" << "," - << "SensorDescriptorId" << "," - << "SensorDescriptorType" << "," - << "SensorDescriptorTransformParentId" << "," - << "SensorDescriptorTransformTimestamp" << "," - << "SensorDescriptorTransformStack0Id" << "," - << "SensorDescriptorTransformStack0Timestamp" << "," - << "SensorDescriptorTransformStack0Origin0" << "," - << "SensorDescriptorTransformStack0Origin1" << "," - << "SensorDescriptorTransformStack0Origin2" << "," - << "SensorDescriptorTransformStack0Orientation0" << "," - << "SensorDescriptorTransformStack0Orientation1" << "," - << "SensorDescriptorTransformStack0Orientation2" << "," - << "SensorDescriptorTransformStack0Orientation3" << "," - << "StartTimestamp" << "," - << "EndTimestamp" << "," - << "NativeStartTimestampFormat" << "," - << "NativeStartTimestampValue" << "," - << "PointsPosition0" << "," - << "PointsPosition1" << "," - << "PointsPosition2" << "," - << "PointsIntensity" << "\n"; - - return; -} - -template<> -void Subscriber< polysync::datamodel::LaneModelMessage >::handleEvents( - std::shared_ptr message ) -{ - if( auto inMessage = - polysync::datamodel::getSubclass< - polysync::datamodel::LaneModelMessage >( message ) ) - { - std::stringstream repeatStream; - - outputHeaderData( repeatStream, inMessage ); - - //Wrap all output around Lanes so header and sensor descriptor - //data repeats - auto outputLanes = inMessage->getLanes(); - - std::vector::iterator - outputLanesIterator; - - for( outputLanesIterator = outputLanes.begin(); - outputLanesIterator != outputLanes.end(); - outputLanesIterator++ ) - { - _outFile - << repeatStream.str() - << outputLanesIterator->getTimestamp() << "," - << ( uint ) outputLanesIterator->getNativeTimestampFormat() << "," - << outputLanesIterator->getNativeTimestampValue() << "," - << outputLanesIterator->getQuality() << "," - << outputLanesIterator->getMarkerType() << "," - << outputLanesIterator->getModelType() << "," - << outputLanesIterator->getMarkerWidth() << "," - << outputLanesIterator->getHeadingAngle() << "," - << outputLanesIterator->getViewRange() << "," - << outputLanesIterator->getMarkerOffset() << "," - << outputLanesIterator->getCurvature() << "," - << outputLanesIterator->getCurvatureDerivative() - << "," - << outputLanesIterator->getTimeToCrossing() << "\n"; - } - } - - return; -} - -template<> -void Subscriber< polysync::datamodel::LaneModelMessage >::outputCSVHeader() -{ - _outFile << "HeaderType" << "," - << "HeaderTimestamp" << "," - << "HeaderSrcGuid" << "," - << "SensorDescriptorId" << "," - << "SensorDescriptorType" << "," - << "SensorDescriptorTransformParentId" << "," - << "SensorDescriptorTransformTimestamp" << "," - << "SensorDescriptorTransformStack0Id" << "," - << "SensorDescriptorTransformStack0Timestamp" << "," - << "SensorDescriptorTransformStack0Origin0" << "," - << "SensorDescriptorTransformStack0Origin1" << "," - << "SensorDescriptorTransformStack0Origin2" << "," - << "SensorDescriptorTransformStack0Orientation0" << "," - << "SensorDescriptorTransformStack0Orientation1" << "," - << "SensorDescriptorTransformStack0Orientation2" << "," - << "SensorDescriptorTransformStack0Orientation3" << "," - << "LanesTimestamp" << "," - << "LanesNativeTimestampFormat" << "," - << "LanesNativeTimestampValue" << "," - << "LanesQuality" << "," - << "LanesMarkerType" << "," - << "LanesModelType" << "," - << "LanesMarkerWidth" << "," - << "LanesHeadingAngle" << "," - << "LanesViewRange" << "," - << "LanesMarkerOffset" << "," - << "LanesCurvature" << "," - << "LanesCurvatureDerivative" << "," - << "LanesTimeToCrossing" << "\n"; - - return; -} - -template<> -void Subscriber< polysync::datamodel::ObjectsMessage >::handleEvents( - std::shared_ptr message ) -{ - - if( auto inMessage = - polysync::datamodel::getSubclass< - polysync::datamodel::ObjectsMessage >( message ) ) - { - std::stringstream repeatStream; - - outputHeaderData( repeatStream, inMessage ); - - //Wrap all output around Objects so header and sensor descriptor - //data repeats - auto outputObjects = inMessage->getObjects(); - - std::vector::iterator - outputObjectsIterator; - - for( outputObjectsIterator = outputObjects.begin(); - outputObjectsIterator != outputObjects.end(); - outputObjectsIterator++ ) - { - auto outputPositions = outputObjectsIterator->getPosition(); - auto outputSize = outputObjectsIterator->getSize(); - auto outputVelocity = outputObjectsIterator->getVelocity(); - - _outFile - << repeatStream.str() - << outputObjectsIterator->getId() << "," - << outputObjectsIterator->getTimestamp() << "," - << ( uint ) outputObjectsIterator->getNativeTimestampFormat() - << "," - << outputObjectsIterator->getNativeTimestampValue() << "," - << outputPositions[ 0 ] << "," - << outputPositions[ 1 ] << "," - << outputPositions[ 2 ] << "," - << outputSize[ 0 ] << "," - << outputSize[ 1 ] << "," - << outputSize[ 2 ] << "," - << outputVelocity[ 0 ] << "," - << outputVelocity[ 1 ] << "," - << outputVelocity[ 2 ] << "," - << outputObjectsIterator->getCourseAngle() << "," - << outputObjectsIterator->getClassification() << "," - << outputObjectsIterator->getClassificationQuality() << "\n"; - } - } - - return; -} - -template<> -void Subscriber< polysync::datamodel::ObjectsMessage >::outputCSVHeader() -{ - _outFile - << "HeaderType" << "," - << "HeaderTimestamp" << "," - << "HeaderSrcGuid" << "," - << "SensorDescriptorId" << "," - << "SensorDescriptorType" << "," - << "SensorDescriptorTransformParentId" << "," - << "SensorDescriptorTransformTimestamp" << "," - << "SensorDescriptorTransformStack0Id" << "," - << "SensorDescriptorTransformStack0Timestamp" << "," - << "SensorDescriptorTransformStack0Origin0" << "," - << "SensorDescriptorTransformStack0Origin1" << "," - << "SensorDescriptorTransformStack0Origin2" << "," - << "SensorDescriptorTransformStack0Orientation0" << "," - << "SensorDescriptorTransformStack0Orientation1" << "," - << "SensorDescriptorTransformStack0Orientation2" << "," - << "SensorDescriptorTransformStack0Orientation3" << "," - << "ObjectsId" << "," - << "ObjectsTimestamp" << "," - << "ObjectsNativeTimestampFormat" << "," - << "ObjectsNativeTimestampValue" << "," - << "ObjectsPosition0" << "," - << "ObjectsPosition1" << "," - << "ObjectsPosition2" << "," - << "ObjectsSize0" << "," - << "ObjectsSize1" << "," - << "ObjectsSize2" << "," - << "ObjectsVelocity0" << "," - << "ObjectsVelocity1" << "," - << "ObjectsVelocity2" << "," - << "ObjectsCourseAngle" << "," - << "ObjectsClassification" << "," - << "ObjectsClassificationQuality" << "\n"; - - return; -} - -template<> -void Subscriber< polysync::datamodel::PlatformMotionMessage >::handleEvents( - std::shared_ptr message ) -{ - - if( auto inMessage = - polysync::datamodel::getSubclass< - polysync::datamodel::PlatformMotionMessage >( message ) ) - { - std::stringstream repeatStream; - - outputHeaderData( repeatStream, inMessage ); - - auto outputPosition = inMessage->getPosition(); - auto outputOrientation = inMessage->getOrientation(); - auto outputRotationRate = inMessage->getRotationRate(); - auto outputVelocity = inMessage->getVelocity(); - auto outputAcceleration = inMessage->getAcceleration(); - - _outFile - << repeatStream.str() - << inMessage->getTimestamp() << "," - << ( uint ) inMessage->getNativeTimestampFormat() << "," - << inMessage->getNativeTimestampValue() << "," - << outputPosition[ 0 ] << "," - << outputPosition[ 1 ] << "," - << outputPosition[ 2 ] << "," - << outputOrientation[ 0 ] << "," - << outputOrientation[ 1 ] << "," - << outputOrientation[ 2 ] << "," - << outputOrientation[ 3 ] << "," - << outputRotationRate[ 0 ] << "," - << outputRotationRate[ 1 ] << "," - << outputRotationRate[ 2 ] << "," - << outputVelocity[ 0 ] << "," - << outputVelocity[ 1 ] << "," - << outputVelocity[ 2 ] << "," - << outputAcceleration[ 0 ] << "," - << outputAcceleration[ 1 ] << "," - << outputAcceleration[ 2 ] << "," - << inMessage->getHeading() << "," - << inMessage->getLatitude() << "," - << inMessage->getLongitude() << "," - << inMessage->getAltitude() << "\n"; - } - - return; -} - -template<> -void Subscriber< polysync::datamodel::PlatformMotionMessage >::outputCSVHeader() -{ - _outFile - << "HeaderType" << "," - << "HeaderTimestamp" << "," - << "HeaderSrcGuid" << "," - << "SensorDescriptorId" << "," - << "SensorDescriptorType" << "," - << "SensorDescriptorTransformParentId" << "," - << "SensorDescriptorTransformTimestamp" << "," - << "SensorDescriptorTransformStack0Id" << "," - << "SensorDescriptorTransformStack0Timestamp" << "," - << "SensorDescriptorTransformStack0Origin0" << "," - << "SensorDescriptorTransformStack0Origin1" << "," - << "SensorDescriptorTransformStack0Origin2" << "," - << "SensorDescriptorTransformStack0Orientation0" << "," - << "SensorDescriptorTransformStack0Orientation1" << "," - << "SensorDescriptorTransformStack0Orientation2" << "," - << "SensorDescriptorTransformStack0Orientation3" << "," - << "Timestamp" << "," - << "NativeTimestampFormat" << "," - << "NativeTimestampValue" << "," - << "Position0" << "," - << "Position1" << "," - << "Position2" << "," - << "Orientation0" << "," - << "Orientation1" << "," - << "Orientation2" << "," - << "Orientation3" << "," - << "RotationRate0" << "," - << "RotationRate1" << "," - << "RotationRate2" << "," - << "Velocity0" << "," - << "Velocity1" << "," - << "Velocity2" << "," - << "Acceleration0" << "," - << "Acceleration1" << "," - << "Acceleration2" << "," - << "Heading" << "," - << "Latitude" << "," - << "Longitude" << "," - << "Altitude" << "\n"; - - return; -} - diff --git a/CSVExporter/SubscriberMap.cpp b/CSVExporter/SubscriberMap.cpp deleted file mode 100644 index af709c4..0000000 --- a/CSVExporter/SubscriberMap.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "SubscriberMap.hpp" - -//A function to initialize the mapping of all node types -SubscriberMap::SubscriberMap() -{ - _initTimestamp = polysync::getTimestamp(); - - _outputMessages[ "ps_radar_targets_msg" ] = - Subscriber< - polysync::datamodel::RadarTargetsMessage >::Create; - _outputMessages[ "ps_lidar_points_msg" ] = - Subscriber< - polysync::datamodel::LidarPointsMessage >::Create; - _outputMessages[ "ps_lane_model_msg" ] = - Subscriber< - polysync::datamodel::LaneModelMessage >::Create; - _outputMessages[ "ps_objects_msg" ] = - Subscriber< - polysync::datamodel::ObjectsMessage >::Create; - _outputMessages[ "ps_platform_motion_msg"] = - Subscriber< - polysync::datamodel::PlatformMotionMessage >::Create; -} - -//Call of actual bridge type spins up a node with any -//parameters which must be set first -polysync::DataSubscriber* SubscriberMap::newType( std::string nodeType ) -{ - return _outputMessages[ nodeType ]( _initTimestamp ); -} - -void SubscriberMap::printMessages() -{ - std::cout << "Available messages are:\n"; - - for( - _messagesIterator = _outputMessages.begin(); - _messagesIterator != _outputMessages.end(); - _messagesIterator++ ) - { - std::cout << _messagesIterator->first << "\n"; - } - -} diff --git a/CSVExporter/include/CSVExport.hpp b/CSVExporter/include/CSVExport.hpp deleted file mode 100644 index f5552e0..0000000 --- a/CSVExporter/include/CSVExport.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef CSVEXPORT_HPP -#define CSVEXPORT_HPP - -#include /* std */ -#include -#include -#include -#include - -#include /* PolySync files */ -#include -#include - -#include "SubscriberMap.hpp" /* Local files */ - -/** - *class Parameters - * This class is used to pass parameters around for command line arguments. - */ -class Parameters -{ -public: - - std::vector messageType; -}; - -/** - * @brief This function is to take in command line arguments and handle them. - * Arguments go to two locations, the Parameters class used in main and - * directly set in the TypeMap which is used through out main. - * - * @param getOpt [in] command line arguments from the GetOpt library. - * - * @param setType [out] the TypeMap where it's parameters are set. - * - * @param setParameters [out] the Parameters class used for main parameters. - */ -int handleOptions( - GetOpt && getOpt, - Parameters * setParameters ); - -/** - * @brief This function prints out the command line options. - */ -void printHelp(); - -/** - * @brief This function prints out an error message for when the Message type - * has not been passed in as an argument. - */ -void printMissingMessageType(); - -#endif // CSVEXPORT_HPP - diff --git a/CSVExporter/include/Subscriber.hpp b/CSVExporter/include/Subscriber.hpp deleted file mode 100644 index 94928a8..0000000 --- a/CSVExporter/include/Subscriber.hpp +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef SUBSCRIBER_HPP -#define SUBSCRIBER_HPP - -#include /* std */ -#include -#include - -#include /* PolySync files */ -#include -#include - - -template < typename psType > class Subscriber : - public polysync::DataSubscriber -{ - -public: - /** - * @brief This function creates an instance of the class with a specific - * node type provided and returns the base class pointer. - * - * @return The base pointer of this class. - */ - static DataSubscriber * Create( unsigned long int timestamp ) - { - return new Subscriber< psType >( timestamp ); - } - - /** - * @brief This is the class construction where the timestamp is syncronized - * in order to provide the same timestamp in each file name created. A new - * file is opened with the name of the message type and the timestamp passed - * in with this function. - * - * @param [in] A polysync timestamp value in order to append the same time - * to each export file of different message types. - */ - Subscriber ( unsigned long int timestamp ) - { - _initTimestamp = timestamp; - - //Connect the Subscriber - connectSubscriberMethod< Subscriber >( - psType::getName(), - &Subscriber::handleEvents, - this ); - - polysync::Application::getInstance()->attachSubscriber( this ); - - //Initialize a CSV with column header dump - std::string filename = - psType::getName() + - "_" + - std::to_string( _initTimestamp ) + - ".csv"; - - _outFile.open( filename, std::ios::app | std::ios::binary ); - - _outFile << std::fixed; - - outputCSVHeader(); - } - - /** - *@brief This function cleanly closes the CSV file and deletes the stream. - */ - ~Subscriber() - { - _outFile.close(); - } - - -private: - - std::ofstream _outFile; - - unsigned long int _initTimestamp; - - /** - * @brief This function is the handler for incoming messages. Where the - * message data will be output to a CSV file stream. - * - * @param [in] the message to be converted to CSV. - */ - void handleEvents( std::shared_ptr< polysync::Message > message ); - - /** - * @brief This function outputs the CSV column header information to the - * file stream after it has been opened. - */ - void outputCSVHeader(); - - /** - * @brief This function is a general output of the header and - * sensor_descriptor information. - * - * @param [out] The stream to output this data. - */ - void outputHeaderData( - std::stringstream & repeatStream, - std::shared_ptr< psType > output ) - { - //Construct repeating row information - repeatStream - << output->getHeaderType() << "," - << output->getHeaderTimestamp() << "," - << output->getHeaderSrcGuid() << "," - << output->getSensorDescriptorId() << "," - << output->getSensorDescriptorType() << "," - << output->getSensorDescriptorTransformParentId() << "," - << output->getSensorDescriptorTransformTimestamp() << ","; - - auto stack = output->getSensorDescriptorTransformStack(); - - if( stack.size() > 0 ) - { - auto origin = stack.front().getOrigin(); - auto orientation = stack.front().getOrientation(); - - repeatStream - << stack.front().getId() << "," - << stack.front().getTimestamp() << "," - << origin[ 0 ] << "," - << origin[ 1 ] << "," - << origin[ 2 ] << "," - << orientation[ 0 ] << "," - << orientation[ 1 ] << "," - << orientation[ 2 ] << "," - << orientation[ 3 ] << ","; - } - else - { - repeatStream << ",,,,,,,,,"; - } - - return; - } - -}; //End Class - -#endif // SUBSCRIBER_HPP diff --git a/CSVExporter/include/SubscriberMap.hpp b/CSVExporter/include/SubscriberMap.hpp deleted file mode 100644 index 5473052..0000000 --- a/CSVExporter/include/SubscriberMap.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef SUBSCRIBERMAP_HPP -#define SUBSCRIBERMAP_HPP - -#include /* std */ -#include - -#include "Subscriber.hpp" /* PolySync */ - -/** - * @class SubscriberMap - * This class is used to map from string to a message type allowing for command - * line arguments. This map uses a template class Subscriber.hpp to - * construct each message type and a Create function which returns the base - * pointer [DataSubscriber]. - * - * @code - * - * SubscriberMap callType; - * - * auto myMessageType = callType.newType( "ps_radar_targets_msg" ); - * - * polysync::Application::getInstance()->connectPolySync(); - * - * delete myMessageType; - * - * @endcode - */ -class SubscriberMap -{ - -public: - SubscriberMap(); - - /** - * @brief This function initializes a node of a specific type from the - * template class. - * - * @param bridgeType [in] the c type name of message to be constructed - * - * @return The base class pointer of polysync::Node* - */ - polysync::DataSubscriber* newType(std::string nodeType); - - /** - * @brief This function prints out the available messages in the map for - * use with the help output in the arguments. - */ - void printMessages(); - -private: - - //The primary map used for calling various node types by string name - std::map< std::string, std::function< polysync::DataSubscriber*( - unsigned long int timestamp ) > > _outputMessages; - std::map< std::string, std::function< polysync::DataSubscriber*( - unsigned long int timestamp ) > >::iterator _messagesIterator; - - unsigned long int _initTimestamp; - -}; - -#endif //SUBSCRIBERMAP_HPP diff --git a/DataGenerator/CMakeLists.txt b/DataGenerator/CMakeLists.txt deleted file mode 100644 index 981a6ad..0000000 --- a/DataGenerator/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-data-generator-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -aux_source_directory( . SRC ) - -add_executable( ${PROJECT_NAME} - ${SRC} -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/DataGenerator/DataGenerator.cpp b/DataGenerator/DataGenerator.cpp deleted file mode 100644 index 1dd66a3..0000000 --- a/DataGenerator/DataGenerator.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example DataGenerator.cpp - * - * PolySync CAN API Reader Example. - * - * Shows how to use the CAN API to read CAN frames. - * - * @file DataGenerator.cpp - * @brief DataGenerator Source - * - */ - -#include - -#include -#include - -#include "LidarPointGenerator.hpp" -#include "RadarTargetGenerator.hpp" -#include "ObjectGenerator.hpp" - - -using namespace polysync::datamodel; - - -class DataGenerator : public polysync::Node -{ - -protected: - - /** - * Override the base class functionality to send messages when the node - * reaches the "ok" state. This method is triggered continuously while - * this node is in an operational state. - */ - virtual void okStateEvent() - { - _lidarPointGenerator->updatePoints(); - - _lidarPointGenerator->publishPoints(); - - _radarTargetGenerator->updateTargets(); - - _radarTargetGenerator->publishTargets(); - - _objectGenerator->updateObjects(); - - _objectGenerator->publishObjects(); - - polysync::sleepMicro( _updateInterval ); - } - - /** - * The initStateEvent is triggered once when this node is initialized in - * PolySync. This is a good place to initialize variables dependant on a - * polysync::Node reference. - */ - virtual void initStateEvent() - { - _lidarPointGenerator = - std::unique_ptr< LidarPointGenerator >{ - new LidarPointGenerator( *this ) }; - - _radarTargetGenerator = - std::unique_ptr< RadarTargetGenerator >{ - new RadarTargetGenerator( *this ) }; - - _objectGenerator = - std::unique_ptr< ObjectGenerator >{ - new ObjectGenerator( *this ) }; - } - - /** - * The release state is called once when polysync::Node::disconnectPolySync() - * is called ( ctrl-c in this case ). In this event, the node is still - * valid in PolySync. We need to release the data generators to allow them - * to free their polysync::datamodel messages while the node is still valid. - */ - virtual void releaseStateEvent() - { - _lidarPointGenerator.release(); - - _radarTargetGenerator.release(); - - _objectGenerator.release(); - } - -private: - - ps_timestamp _updateInterval{ 50000 }; - - std::unique_ptr< LidarPointGenerator > _lidarPointGenerator; - - std::unique_ptr< RadarTargetGenerator > _radarTargetGenerator; - - std::unique_ptr< ObjectGenerator > _objectGenerator; - -}; - -/** - * Entry point for the publisher side of this tutorial application - * The "connectPolySync" is a blocking call, users must use Ctrl-C to exit - * this function. - */ -int main() -{ - DataGenerator dataGenerator; - - dataGenerator.connectPolySync(); - - return 0; -} diff --git a/DataGenerator/LidarPointGenerator.cpp b/DataGenerator/LidarPointGenerator.cpp deleted file mode 100644 index 98a65b0..0000000 --- a/DataGenerator/LidarPointGenerator.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * @file LidarPointGenerator.cpp - * @brief LidarPointGenerator Source - * - */ - -#include "LidarPointGenerator.hpp" - -using namespace std; -using namespace polysync::datamodel; - -LidarPointGenerator::LidarPointGenerator( polysync::Node & node ) - : - _message( node ), - _numberOfPoints( _gridSideLength * _gridSideLength ) -{ - initializeMessage(); -} - -void LidarPointGenerator::initializeMessage() -{ - polysync::datamodel::SensorDescriptor descriptor; - - descriptor.setId( 11 ); - - descriptor.setTransformParentId( PSYNC_COORDINATE_FRAME_LOCAL ); - - descriptor.setType( PSYNC_SENSOR_KIND_NOT_AVAILABLE ); - - _message.setSensorDescriptor( descriptor ); - - auto time = polysync::getTimestamp(); - - _message.setHeaderTimestamp( time ); - - _message.setStartTimestamp( time ); - - _message.setEndTimestamp( time ); - - - updatePoints(); -} - -void LidarPointGenerator::updatePoints() -{ - auto time = polysync::getTimestamp(); - - auto timeDelta = time - _message.getStartTimestamp(); - - auto timeDeltaSeconds = static_cast< float >( timeDelta ) / 1000000.0; - - _relativeTime += timeDeltaSeconds; - - _message.setStartTimestamp( time ); - - _message.setEndTimestamp( time ); - - std::vector< LidarPoint > outputPoints; - - outputPoints.reserve( _numberOfPoints ); - - for( auto pointNum = 0U; pointNum < _numberOfPoints; ++pointNum ) - { - polysync::datamodel::LidarPoint point; - - point.setIntensity( 255 ); - - auto x = pointNum % 100; - - auto y = pointNum / 100; - - float u = static_cast< float >( x )/ 100.0; - - float v = static_cast< float >( y ) / 100.0; - - // center u/v at origin - u = ( u * 2.0 ) - 1.0; - - v = ( v * 2.0 ) - 1.0; - - float w = sin( ( u * _sineFrequency ) + _relativeTime ) * - cos( ( v * _sineFrequency ) + _relativeTime ) * - 0.5; - - point.setPosition( { u * 10, v * 10, w * 10 } ); - - outputPoints.emplace_back( point ); - } - - _message.setPoints( outputPoints ); -} - -void LidarPointGenerator::publishPoints() -{ - _message.setHeaderTimestamp( polysync::getTimestamp() ); - - _message.publish(); -} diff --git a/DataGenerator/LidarPointGenerator.hpp b/DataGenerator/LidarPointGenerator.hpp deleted file mode 100644 index 453b95d..0000000 --- a/DataGenerator/LidarPointGenerator.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * @file LidarPointGenerator.hpp - * @brief LidarPointGenerator Source - * - */ - -#ifndef LIDARPOINTS_HPP -#define LIDARPOINTS_HPP - -#include -#include - - -class LidarPointGenerator -{ -public: - LidarPointGenerator( polysync::Node & ); - - void updatePoints(); - - void publishPoints(); - - void initializeMessage(); - -private: - - polysync::datamodel::LidarPointsMessage _message; - - float _relativeTime{ 0.0 }; - const float _gridScale{ 10.0 }; - const ulong _gridSideLength{ 100 }; - const ulong _sensorID{ 11 }; - const ulong _numberOfPoints{ 10000 }; - const float _sineFrequency{ 4.0 }; -}; - -#endif // LIDARPOINTS_HPP diff --git a/DataGenerator/ObjectGenerator.cpp b/DataGenerator/ObjectGenerator.cpp deleted file mode 100644 index ca2e78d..0000000 --- a/DataGenerator/ObjectGenerator.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * @file ObjectGenerator.cpp - * @brief ObjectGenerator Source - * - */ - -#include "ObjectGenerator.hpp" - -ObjectGenerator::ObjectGenerator( polysync::Node & node ) - : - _message( node ) -{ - initializeMessage(); -} - -void ObjectGenerator::initializeMessage() -{ - polysync::datamodel::SensorDescriptor descriptor; - - descriptor.setId( _sensorID ); - - descriptor.setTransformParentId( PSYNC_COORDINATE_FRAME_LOCAL ); - - descriptor.setType( PSYNC_SENSOR_KIND_NOT_AVAILABLE ); - - _message.setSensorDescriptor( descriptor ); - - _message.setHeaderTimestamp( polysync::getTimestamp() ); - - resetObjects(); - - _message.setObjects( _objectVector ); -} - -void ObjectGenerator::updateObjects() -{ - auto time = polysync::getTimestamp(); - - // for each target - for( auto index = 0; index < _objectCount; ++index ) - { - // Get time difference from last update - auto timeDelta = time - _message.getHeaderTimestamp(); - - // Convert to seconds - auto timeDeltaSeconds = static_cast< double >( timeDelta )/ 1000000.0; - - auto position = _objectVector[ index ].getPosition(); - - // update position using p = p_0 + v * dt - _objectVector[ index ].setPosition( - { position[ 0 ] + _velocityX * timeDeltaSeconds, - position[ 1 ] + _velocityY * timeDeltaSeconds, - 0.0 } ); - - // set timestamp - _objectVector[ index ].setTimestamp( time ); - - if( _objectVector[ index ].getPosition()[ 0 ] > 30.0 ) - { - _reset = true; - } - } - - // if reset flag set - if( _reset ) - { - resetObjects(); - } - - _message.setObjects( _objectVector ); - - // set header timestamp - _message.setHeaderTimestamp( time ); -} - -void ObjectGenerator::resetObjects() -{ - _objectVector = {}; - for( auto index = 0; index < _objectCount; ++index ) - { - polysync::datamodel::Object object; - - object.setPosition( { ( index + 2 ) * 2.0, - ( index + 2 ) * 4.0, - 0.5 } ); - - object.setSize( { _objectSizeX, - _objectSizeY, - _objectSizeZ } ); - - object.setCourseAngle( atan2( _velocityY, _velocityX ) ); - - object.setVelocity( { _velocityX, _velocityY, 0.0 } ); - - object.setClassification( OBJECT_CLASSIFICATION_CAR ); - - object.setClassificationQuality( QUALITY_9 ); - - _objectVector.emplace_back( object ); - } - - _reset = false; -} - -void ObjectGenerator::publishObjects() -{ - _message.setHeaderTimestamp( polysync::getTimestamp() ); - - _message.publish(); -} diff --git a/DataGenerator/ObjectGenerator.hpp b/DataGenerator/ObjectGenerator.hpp deleted file mode 100644 index 3bb1873..0000000 --- a/DataGenerator/ObjectGenerator.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * @file ObjectGenerator.hpp - * @brief ObjectGenerator Source - * - */ - -#ifndef OBJECTGENERATOR_HPP -#define OBJECTGENERATOR_HPP - -#include -#include - -class ObjectGenerator -{ -public: - ObjectGenerator( polysync::Node & ); - - void initializeMessage(); - void resetObjects(); - void updateObjects(); - void publishObjects(); - -private: - polysync::datamodel::ObjectsMessage _message; - std::vector< polysync::datamodel::Object > _objectVector; - - const ps_identifier _sensorID{ 12 }; - const int _objectCount{ 2 }; - const double _objectSizeX{ 2.0 }; - const double _objectSizeY{ 1.5 }; - const double _objectSizeZ{ 1.0 }; - const double _velocityX{ 3.5 }; - const double _velocityY{ -3.5 }; - bool _reset{ false }; -}; - -#endif // OBJECTGENERATOR_HPP diff --git a/DataGenerator/README.md b/DataGenerator/README.md deleted file mode 100644 index a29eb5e..0000000 --- a/DataGenerator/README.md +++ /dev/null @@ -1,34 +0,0 @@ -### DataGenerator - -This example covers how to populate and publish data from a single node into a PolySync message on the bus, -enable multiple nodes to subscribe to messages to access data asynchronously, and visualize all data being -published to the PolySync bus. - -This example generates data and publishes it on the PolySync bus by generating fake radar, lidar, and object data. -It periodically publishes `ps_lidar_points_msg`, `ps_radar_targets_msg`, and `ps_objects_msg` to the bus in the OK state. -It uses a lightweight diagnostic tool to tell if a system is properly up and running. - -There is an article in the PolySync Help Center that describes the C++ version of this example: -[Data Generation Tutorial](https://help.polysync.io/articles/tutorials-and-examples/tutorials/data-generation-tutorial/) - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd DataGenerator -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-data-generator-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/DataGenerator/RadarTargetGenerator.cpp b/DataGenerator/RadarTargetGenerator.cpp deleted file mode 100644 index d3a39e0..0000000 --- a/DataGenerator/RadarTargetGenerator.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * @file RadarTargetGenerator.cpp - * @brief RadarTargetGenerator Source - * - */ - -#include "RadarTargetGenerator.hpp" - -RadarTargetGenerator::RadarTargetGenerator( polysync::Node & node ) - : - _message( node ) -{ - initializeMessage(); -} - -void RadarTargetGenerator::initializeMessage() -{ - polysync::datamodel::SensorDescriptor descriptor; - - descriptor.setId( _sensorID ); - - descriptor.setTransformParentId( PSYNC_COORDINATE_FRAME_LOCAL ); - - descriptor.setType( PSYNC_SENSOR_KIND_NOT_AVAILABLE ); - - _message.setSensorDescriptor( descriptor ); - - _message.setHeaderTimestamp( polysync::getTimestamp() ); - - resetTargets(); - - _message.setTargets( _targetVector ); -} - -void RadarTargetGenerator::updateTargets() -{ - auto time = polysync::getTimestamp(); - - // for each target - for( auto index = 0; index < _targetsCount; ++index ) - { - // Get time difference from last update - auto timeDelta = time - _message.getHeaderTimestamp(); - - // Convert to seconds - auto timeDeltaSeconds = static_cast< double >( timeDelta )/ 1000000.0; - - auto position = _targetVector[ index ].getPosition(); - - // update position using p = p_0 + v * dt - _targetVector[ index ].setPosition( - { position[ 0 ] + _velocityX * timeDeltaSeconds, - position[ 1 ] + _velocityY * timeDeltaSeconds, - 0.0 } ); - - // set timestamp - _targetVector[ index ].setTimestamp( time ); - - if( _targetVector[ index ].getPosition()[ 0 ] > 30.0 ) - { - _reset = true; - } - } - - // if reset flag set - if( _reset ) - { - resetTargets(); - } - - _message.setTargets( _targetVector ); - - // set header timestamp - _message.setHeaderTimestamp( time ); -} - -void RadarTargetGenerator::resetTargets() -{ - _targetVector = {}; - for( auto index = 0; index < _targetsCount; ++index ) - { - polysync::datamodel::RadarTarget target; - - target.setSize( { PSYNC_SIZE_NOT_AVAILABLE, - PSYNC_SIZE_NOT_AVAILABLE, - PSYNC_SIZE_NOT_AVAILABLE } ); - - target.setRangeType( RANGE_NOT_AVAILABLE ); - - target.setZoneType( ZONE_NOT_AVAILABLE ); - - target.setQuality( QUALITY_NOT_AVAILABLE ); - - target.setMagnitude( PSYNC_MAGNITUDE_NOT_AVAILABLE ); - - target.setAlias( PSYNC_VELOCITY_ALIAS_NOT_AVAILABLE ); - - target.setCrossSection( PSYNC_RADAR_CROSS_SECTION_NOT_AVAILABLE ); - - target.setScanIndex( 0 ); - - target.setId( index + 1 ); - - target.setTrackStatus( TRACK_STATUS_ACTIVE ); - - target.setTimestamp( polysync::getTimestamp() ); - - target.setAmplitude( _amplitude ); - - target.setPosition( { ( index + 2 ) * 2.0, - ( index + 2 ) * 4.0, - 0.5 } ); - - target.setVelocity( { _velocityX, _velocityY, 0.0 } ); - - _targetVector.emplace_back( target ); - } - - _reset = false; -} - -void RadarTargetGenerator::publishTargets() -{ - _message.setHeaderTimestamp( polysync::getTimestamp() ); - - _message.publish(); -} diff --git a/DataGenerator/RadarTargetGenerator.hpp b/DataGenerator/RadarTargetGenerator.hpp deleted file mode 100644 index 54d2c71..0000000 --- a/DataGenerator/RadarTargetGenerator.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * @file RadarTargetGenerator.hpp - * @brief RadarTargetGenerator Header. - * - */ - -#ifndef RADARTARGETGENERATOR_HPP -#define RADARTARGETGENERATOR_HPP - -#include -#include - -class RadarTargetGenerator -{ -public: - RadarTargetGenerator( polysync::Node & ); - - void initializeMessage(); - void updateTargets(); - void publishTargets(); - void resetTargets(); - -private: - polysync::datamodel::RadarTargetsMessage _message; - - std::vector< polysync::datamodel::RadarTarget > _targetVector; - - const ps_identifier _sensorID { 11 }; - const int _targetsCount{ 2 }; - const double _amplitude{ 2.0 }; - const double _velocityX{ 3.5 }; - const double _velocityY{ 3.5 }; - bool _reset{ false }; -}; - -#endif // RADARTARGETGENERATOR_HPP diff --git a/Echo/ApplicationInputHandler.cpp b/Echo/ApplicationInputHandler.cpp deleted file mode 100644 index 57a9947..0000000 --- a/Echo/ApplicationInputHandler.cpp +++ /dev/null @@ -1,248 +0,0 @@ -#include -#include -#include - -#include "ApplicationInputHandler.hpp" - - -ApplicationInputHandler::ApplicationInputHandler() - : - _userFileName( {} ), - _activeMessagesFlag( false ), - _ignoreSelfFlag( false ), - _filteredForMessagesFlag( false ), - _echoMessageHeadersOnlyFlag( false ), - _echoMessageToFileFlag( false ), - _echoMessageToFileNoStdOutFlag( false ), - _getOptHelpFlag( false ), - _durationSpecifiedFlag( false ), - _filteredMessageNames( {} ) -{ - // empty -} - - -bool ApplicationInputHandler::optionsParse( const int argc, char * argv[] ) -{ - bool parsedOptSuccess = true; - - int optionIndex = -1; - - // reset scanner - optind = 0; - - opterr = 0; - - while ( ( optionIndex = getopt( argc, argv, "t:o:O:f:hH::a::i::") ) != -1 ) - { - switch( optionIndex ) - { - case 'a': - - _activeMessagesFlag = true; - - break; - - case 'i': - - _ignoreSelfFlag = true; - - break; - - case 'f': - - if( ( *argv[ optind - 1 ] ) - && ( *argv[ optind - 1 ] == '-' ) ) - { - std::cout << std::endl << std::endl - << "Invalid usage for option -f filter single " - << "message type:" - << std::endl - <<"-f should be followed by a PolySync " - << "message type, not by another -option." - << std::endl - <<"A usage guide follows." << std::endl; - - _getOptHelpFlag = true; - } - else - { - _filteredForMessagesFlag = true; - - _filteredMessageNames.emplace_back( optarg ); - } - - break; - - case 'o': - - if( ( *argv[ optind - 1 ] ) - && ( *argv[ optind - 1 ] == '-' ) ) - { - std::cout << std::endl << std::endl - << "Invalid usage for option -o external file:" - << std::endl - << "-o should be followed by a filename " - << "yourfile.txt, not by another -option." - << std::endl << std::endl - << "A usage guide follows." - << std::endl; - - _getOptHelpFlag = true; - } - else - { - _userFileName = optarg; - - _echoMessageToFileFlag = true; - } - - break; - - case 'O': - - if( ( *argv[ optind - 1 ] ) - && ( *argv[ optind - 1 ] == '-' ) ) - { - std::cout << std::endl << std::endl - << "Invalid usage for option -O external file:" - << std::endl - << "-O should be followed by a filename " - << "yourfile.txt, not by another -option." - << std::endl << std::endl - << "A usage guide follows." - << std::endl; - - _getOptHelpFlag = true; - } - else - { - _userFileName = optarg; - - _echoMessageToFileFlag = true; - _echoMessageToFileNoStdOutFlag = true; - } - - break; - - case 't': - - if( ( *argv[ optind - 1 ] ) - && ( *argv[ optind - 1 ] == '-' ) ) - { - std::cout << std::endl << std::endl - << "Invalid usage for option -t run for specific time:" - << std::endl - << "-t should be followed by how long you want Echo to" - << " run (sec), not by another -option." - << std::endl - << "A usage guide follows." - << std::endl; - - _getOptHelpFlag = true; - } - else if( ( *argv[ optind - 1 ] ) - && isalpha( *argv[ optind - 1 ] ) ) - { - std::cout << std::endl << std::endl - << "Invalid usage for option -t run for specific time:" - << std::endl - << "-t should be followed by a number" - <<" representing how long you want Echo to run." - << std::endl - << "A usage guide follows." - << std::endl; - - _getOptHelpFlag = true; - } - else - { - _duration = std::stoull( optarg ); - - _durationSpecifiedFlag = true; - } - - break; - - case 'h': - - _getOptHelpFlag = true; - - break; - - case 'H': - - _echoMessageHeadersOnlyFlag = true; - - break; - - default: break; - } - } - - return parsedOptSuccess; -} - - -std::vector< std::string > ApplicationInputHandler::getFilteredMessageNames() const -{ - return _filteredMessageNames; -} - - -std::string ApplicationInputHandler::getFileName() const -{ - return _userFileName; -} - - -bool ApplicationInputHandler::messageTypesWereFiltered() const -{ - return _filteredForMessagesFlag; -} - - -bool ApplicationInputHandler::headersWereRequested() const -{ - return _echoMessageHeadersOnlyFlag; -} - - -bool ApplicationInputHandler::fileWasSpecified() const -{ - return _echoMessageToFileFlag; -} - -bool ApplicationInputHandler::fileWasSpecifiedNoStdOut() const -{ - return _echoMessageToFileNoStdOutFlag; -} - -bool ApplicationInputHandler::helpWasRequested() const -{ - return _getOptHelpFlag; -} - - -bool ApplicationInputHandler::activeTypesWereRequested() const -{ - return _activeMessagesFlag; -} - - -bool ApplicationInputHandler::durationWasSpecified () const -{ - return _durationSpecifiedFlag; -} - - -bool ApplicationInputHandler::ignoreSelfWasRequested() const -{ - return _ignoreSelfFlag; -} - - -unsigned long long ApplicationInputHandler::getUserSpecifiedDuration () const -{ - return _duration; -} diff --git a/Echo/ApplicationInputHandler.hpp b/Echo/ApplicationInputHandler.hpp deleted file mode 100644 index 8152298..0000000 --- a/Echo/ApplicationInputHandler.hpp +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file ApplicationInputHandler.hpp - * @brief Input Handling for Echo Command Line Utility. - * - * PUBLIC_HEADER - */ - -#ifndef APPLICATIONINPUTHANDLER_HPP -#define APPLICATIONINPUTHANDLER_HPP - - -/** - * @brief ApplicationInputHandler class - * - * The ApplicationInputHandler C++ class exists to build upon the C-based getopt class. - * Getopt parses command line input, and validates that input with options, - * arguments, and option-arguments. - */ -class ApplicationInputHandler -{ - -public: - - /** - * @brief ApplicationInputHandler constructor, initialize private data - */ - ApplicationInputHandler(); - - /** - * @brief Parses cmd line arguments in C getopt style. - * - * @param argv Argument vector. - * @param argc Argument count. - * - * @return Returns true if options were parsed successfully. - */ - bool optionsParse( const int argc, char * argv[] ); - - /** - * @brief Member variable getter for multiple filtered message names. - * - * @return Returns std::vector containing multiple message names. - */ - std::vector < std::string > getFilteredMessageNames() const; - - /** - * @brief Member variable getter for user-defined file name, so that - * user can print Echo output to file. - * - * @return Returns std::string containing user-defined file name. - */ - std::string getFileName() const; - - /** - * @brief Member variable getter for command line getopt handling. - * - * @return Returns true if single or multiple message types were filtered. - */ - bool messageTypesWereFiltered() const; - - /** - * @brief Member variable getter for command line getopt handling. - * - * @return Returns true if only message headers (not data) were requested. - */ - bool headersWereRequested() const; - - /** - * @brief Member variable getter for command line getopt handling. - * - * @return Returns boolean: true if user specified external file for output. - */ - bool fileWasSpecified() const; - - /** - * @brief Member variable getter for command line getopt handling. - * - * @return Returns boolean: true if user specified external file for output - * and does wants to forgo reporting to stdout. - */ - bool fileWasSpecifiedNoStdOut() const; - /** - * @brief Member variable getter for command line getopt handling. - * - * @return Returns boolean: true if user either requested help directly, - * or user entered invalid options/arguments on command line. - * - * If help flag true, PolySync nodes do not start up; help is displayed. - */ - bool helpWasRequested() const; - - /** - * @brief Member variable getter for command line getopt handling. - * - * @return Returns true if user specified a duration for Echo. - */ - bool durationWasSpecified() const; - - /** - * @brief Member variable getter for command line getopt handling. - * - * @return true if "-a" flag was correctly input, this will output message - * types that PolySync nodes have registered for publishing. - */ - bool activeTypesWereRequested() const; - - /** - * @brief Member variable getter for command line getopt handling. - * - * @return true if "-i" flag was input to the command line. This will - * not output ps_diagnostic_trace_msg data from this node. - */ - bool ignoreSelfWasRequested() const; - - /** - * @brief Member variable getter for command line getopt handling. - * - * @return Returns unsigned long long to compute difference in UTC microsec. - */ - unsigned long long getUserSpecifiedDuration() const; - -private: - - std::string _userFileName; - - unsigned long long _duration; - - bool _activeMessagesFlag; - - bool _ignoreSelfFlag; - - bool _filteredForMessagesFlag; - - bool _echoMessageHeadersOnlyFlag; - - bool _echoMessageToFileFlag; - - bool _echoMessageToFileNoStdOutFlag; - - bool _getOptHelpFlag; - - bool _durationSpecifiedFlag; - - std::vector < std::string > _filteredMessageNames; - -}; - - -#endif // APPLICATIONINPUTHANDLER_HPP diff --git a/Echo/CMakeLists.txt b/Echo/CMakeLists.txt deleted file mode 100644 index ab8b1c8..0000000 --- a/Echo/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-echo ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - . - ${PSYNC_HOME}/include - ${PSYNC_HOME}/pdm - ${PSYNC_HOME}/include/deps/dcps/C/SAC - ${PSYNC_HOME}/include/deps/sys - ) - -add_executable( ${PROJECT_NAME} - Echo.cpp - EchoNode.cpp - ApplicationInputHandler.cpp - EchoHelp.cpp - ) - -target_link_libraries( - ${PROJECT_NAME} - polysync++ - polysync_cpp_message_support - polysync_data_model - ) diff --git a/Echo/Echo.cpp b/Echo/Echo.cpp deleted file mode 100644 index c453a9a..0000000 --- a/Echo/Echo.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -/** - * \example Echo.cpp - * - * PolySync Echo C++ API example application - * - * Demonstrates a command line utility for echoing PolySync messges to stdout - * - * @file Echo.cpp - * @brief Echo Source - * - */ - -#include "EchoNode.hpp" - - -/** - * Entry point for this tutorial application - * The "connectPolySync" begins this node's PolySync execution loop. - * - * @param argc - int, the number of parameters on the command-line - * @param argv - char* [], the parsed command-line arguments - * - * @return int - exit code - */ -int main( int argc, char *argv[] ) -{ - // Create an instance of the PolySyncEcho and connect it to PolySync. - PolySyncEcho echo; - - - // Nodes will only connect if help option -h not used, - // and, if all arguments are valid. - if ( echo.optionsParse( argc, argv ) ) - { - if ( echo.helpWasRequested() ) - { - echo.printEchoHelpPage(); - } - else - { - // Begin the PolySync event loop. - echo.connectPolySync(); - } - } - - // For a brief tutorial on the Echo tool, run help: $ polysync-echo -h - - return 0; -} diff --git a/Echo/EchoHelp.cpp b/Echo/EchoHelp.cpp deleted file mode 100644 index 5a6c642..0000000 --- a/Echo/EchoHelp.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include - -#include "EchoHelp.hpp" - - -std::vector< std::string > EchoHelp::getHelpFlags() const -{ - std::vector< std::string > cmdLineFlagsHelp; - - cmdLineFlagsHelp.emplace_back( "-h" ); - cmdLineFlagsHelp.emplace_back( "-a" ); - cmdLineFlagsHelp.emplace_back( "-i" ); - cmdLineFlagsHelp.emplace_back( "-f " ); - cmdLineFlagsHelp.emplace_back( "-H" ); - cmdLineFlagsHelp.emplace_back( "-o " ); - cmdLineFlagsHelp.emplace_back( "-O " ); - cmdLineFlagsHelp.emplace_back( "-t " ); - - return cmdLineFlagsHelp; -} - - -std::vector< std::string > EchoHelp::getHelpDescriptions() const -{ - std::vector< std::string > flagDescriptionsHelp; - - flagDescriptionsHelp.emplace_back - ( " Show this help message [optional]." ); - - flagDescriptionsHelp.emplace_back - ( " Output message types that have been discovered by PolySync. \n" - " Usage: " - " $ polysync-echo -a" ); - - flagDescriptionsHelp.emplace_back - ( " Ignore messages from this node. \n" - " Usage: " - " $ polysync-echo -i" ); - - flagDescriptionsHelp.emplace_back - ( " Filter for a single message type OR multiple message types [optional]. \n" - " Usage Example 1: Single Message: " - " $ polysync-echo -f ps_diagnostic_trace_msg \n\n" - " Usage Example 2: Multiple Messages: \n" - " $ polysync-echo -f ps_diagnostic_trace_msg" - " -f ps_lidar_points_msg \n\n" - " Usage Example 3: Multiple Messages, Headers Only: \n $ polysync-echo" - " -f ps_diagnostic_trace_msg -f ps_lidar_points_msg -H \n\n" - " Usage Example 4: Multiple Messages, Headers Only, and print to file: \n" - " $ polysync-echo -f ps_diagnostic_trace_msg -H -o yourFileName.txt \n" - " -f ps_lidar_points_msg \n\n" - " To see a list of message types: $ polysync-echo -f PolySyncMessageType \n\n" - " To see sample messages on bus, run Data Generation Tutorial in \n " - "one Terminal window, and run Echo Utility in a second Terminal window.\n\n" - " Running $ polysync-echo with no -f filter flags prints ALL messages on bus."); - - flagDescriptionsHelp.emplace_back - ( " Echo only message headers [optional]. \n" - " Usage Example 1: echo headers for all message types: \n" - " $ polysync-echo -H \n" - " Usage Example 2: echo headers for single message type: \n" - " $ polysync-echo -f ps_lidar_points_msg -H" ); - - flagDescriptionsHelp.emplace_back - ( " Specify an external output file for printed message data, \n" - " in addition to standard output [optional]. \n" - " Usage Example: print only headers for single message type to file: \n" - " $ polysync-echo -f ps_lidar_points_msg -H -o yourFileName.txt \n\n" - " Note: Unless you specify a new file each time, each session will \n" - " append to the end of your specified file."); - - flagDescriptionsHelp.emplace_back - ( " Specify an external output file for printed message data \n" - " and forgo standard output [optional]. \n" - " Usage Example: print only headers for single message type to file: \n" - " $ polysync-echo -O yourFileName.txt \n\n" - " Note: Unless you specify a new file each time, each session will \n" - " append to the end of your specified file."); - - flagDescriptionsHelp.emplace_back - ( " Specify the amount of time Echo should run for [optional]. \n" - " Usage Example: Run Echo for 10 seconds: \n" - " $ polysync-echo -t 10" ); - - return flagDescriptionsHelp; -} - - -void EchoHelp::printHelp( - const std::vector< std::string > & helpFlags , - const std::vector< std::string> & helpDescriptions ) const -{ - std::cout << "\nPolySync Echo \n" - "Standard behavior (no options) is to echo all messages " - "currently on the bus. \n\n"; - - std::cout << "Usage: \n $polysync-echo [options] \n\n"; - - for( auto index = 0U; index < getHelpFlags().size(); ++index ) - { - std::cout << helpFlags[ index ] << std::endl; - - std::cout << helpDescriptions[ index ] < - variable contains help descriptions. - * - */ - std::vector< std::string > getHelpFlags() const; - - /** - * @brief Get strings for help page display of descriptions for cmd line flags. - * @return std::vector< std::string > - variable contains help descriptions. - * - */ - std::vector< std::string > getHelpDescriptions() const; - - /** - * @brief Print strings for help page display, append to end of list. - * @param std::vector< std:: string > - variable containing help string. - */ - void printHelp( - const std::vector< std::string > & helpFlags, - const std::vector< std::string > & helpDescriptions) const; - - /** - * @brief Wrapper for caller class access to printHelp(). - */ - void printEchoHelp() const; - -}; - - -#endif // ECHOHELP_HPP diff --git a/Echo/EchoNode.cpp b/Echo/EchoNode.cpp deleted file mode 100644 index 90e9a19..0000000 --- a/Echo/EchoNode.cpp +++ /dev/null @@ -1,266 +0,0 @@ -#include - -#include - -#include "EchoNode.hpp" -#include "ApplicationInputHandler.hpp" - - -void PolySyncEcho::initStateEvent() -{ - _applicationStartTime = polysync::getTimestamp(); - - if( _inputHandler.messageTypesWereFiltered() ) - { - registerFilteredMessages(); - } - else if( _inputHandler.activeTypesWereRequested() ) - { - // do nothing - } - else - { - registerListenerToAllMessageTypes(); - } - - if( ! _inputHandler.fileWasSpecifiedNoStdOut() ) - { - std::cout << "{\"polysync-echo\":["; - } - - if( _inputHandler.fileWasSpecified() ) - { - _openUserFile.open( _inputHandler.getFileName(), std::ios::app ); - - if( _openUserFile ) - { - _openUserFile << "{\"polysync-echo\":["; - } - else - { - std::cerr << - "Unable to open '_inputHandler.getFileName()' for writing" << - std::endl; - - activateFault( DTC_IOERR, NODE_STATE_FATAL); - } - } -} - - -void PolySyncEcho::okStateEvent() -{ - if( _inputHandler.durationWasSpecified() ) - { - if( durationReached() ) - { - std::cout << std::endl << std::endl << std::endl - << "Disconnecting PolySync successfully:" - << std::endl - << "The time you've specified with -t option argument has " - << "expired." - << std::endl << std::endl << std::endl; - - disconnectPolySync(); - } - } - - if( _inputHandler.activeTypesWereRequested() ) - { - printActiveMessageTypes(); - } - - polysync::sleepMicro( SecondsToMicro ); -} - -void PolySyncEcho::releaseStateEvent() -{ - if( ! _inputHandler.fileWasSpecifiedNoStdOut() ) - { - std::cout << "]}" << std::endl; - } - - if( _openUserFile ) - { - _openUserFile << "]}" << std::endl; - _openUserFile.close(); - } -} - - -void PolySyncEcho::registerFilteredMessages() -{ - for( auto messageName : _inputHandler.getFilteredMessageNames() ) - { - tryCatchRegisterAMessageListener( messageName ); - } -} - - -void PolySyncEcho::tryCatchRegisterAMessageListener( std::string messageName ) -{ - try - { - registerListener( getMessageTypeByName ( messageName ) ); - } - catch ( ... ) - { - std::cout << std::endl - << "Please enter a valid PS message type:" - << std::endl << std::endl; - - printAvailableMessage( getAvailableMessageNames() ); - - disconnectPolySync(); - } -} - - -void PolySyncEcho::messageEvent( std::shared_ptr< polysync::Message > message ) -{ - if( ( message->getHeaderSrcGuid() == getGuid() ) && - _inputHandler.ignoreSelfWasRequested() ) - { - return; - } - - if( _openUserFile ) - { - printToFile( message ); - } - - if( ! _inputHandler.fileWasSpecifiedNoStdOut() ) - { - printMessage( message ); - } -} - - -void PolySyncEcho::printToFile( - std::shared_ptr < polysync:: Message > message ) -{ - static bool is_first_print = true; - - if( is_first_print ) - { - is_first_print = false; - } - else - { - _openUserFile << ","; - } - - if( _inputHandler.headersWereRequested() ) - { - message->printHeader( _openUserFile ); - } - else - { - message->print( _openUserFile ); - } -} - - -void PolySyncEcho::printMessage( - std::shared_ptr < polysync:: Message > message ) const -{ - static bool is_first_print = true; - - if( is_first_print ) - { - is_first_print = false; - } - else - { - if( ! _inputHandler.fileWasSpecifiedNoStdOut() ) - { - std::cout << ","; - } - } - - if( _inputHandler.headersWereRequested() ) - { - message->printHeader(); - } - else - { - message->print(); - } -} - - -bool PolySyncEcho::optionsParse( const int argc, char * argv[] ) -{ - return _inputHandler.optionsParse( argc, argv ); -} - - -bool PolySyncEcho::helpWasRequested( ) const -{ - return _inputHandler.helpWasRequested(); -} - - -std::vector< std::string > PolySyncEcho::getAvailableMessageNames() const -{ - std::vector< std::string > messageNames; - - for( auto index = 1U; - index < getAvailableMessageCount() + 1; - ++index ) - { - messageNames.emplace_back( getMessageNameByType( index ) ); - } - - return messageNames; -} - - -void PolySyncEcho::printAvailableMessage( - const std::vector< std::string > & messageTypeStrings ) const -{ - for( auto messageTypeString : messageTypeStrings ) - { - std::cout << " " << messageTypeString << std::endl; - } -} - - -void PolySyncEcho::printEchoHelpPage() const -{ - echoHelp.printEchoHelp(); -} - - -void PolySyncEcho::printActiveMessageTypes() const -{ - polysync::RuntimeInfo info( *this ); - - auto typeInfoList = info.getDiscoveredMessageTypes(); - - std::cout << std::endl << std::endl - << "Active PolySync Message Types: " - << std::endl; - - for( auto typeInfo : typeInfoList ) - { - if( typeInfo.getMessageType() != PSYNC_MSG_TYPE_INVALID ) - { - std::cout << " " - << typeInfo.getTypeName() - << std::endl; - } - } -} - - -bool PolySyncEcho::durationReached() const -{ - return ( polysync::getTimestamp() - _applicationStartTime ) >= getDuration(); -} - - -ps_timestamp PolySyncEcho::getDuration() const -{ - return _inputHandler.getUserSpecifiedDuration() * SecondsToMicro; -} diff --git a/Echo/EchoNode.hpp b/Echo/EchoNode.hpp deleted file mode 100644 index cd82fbc..0000000 --- a/Echo/EchoNode.hpp +++ /dev/null @@ -1,174 +0,0 @@ -/** - * @file PolySyncEcho.hpp - * @brief PolySync Echo Messages Command Line Utility. - * - * PUBLIC_HEADER - */ - -#ifndef POLYSYNC_ECHO_HPP -#define POLYSYNC_ECHO_HPP - -#include - -#include - -#include "ApplicationInputHandler.hpp" -#include "EchoHelp.hpp" - -/** - * @brief PolySyncEcho class - * - * The PolySyncEcho class exists to override the functions defined - * in the base Node class. The functions exist in the base class but are - * stubbed out and must be overloaded in order for them to do something. In - * this instance the initStateEvent and the messageHandlerEvent are overloaded - * to register for the messages and receive them, respectively. - */ -class PolySyncEcho : public polysync::Node -{ - -public: - - /** - * @brief Override polysync::Node::initStateEvent() - * - * Subscribe to a message that the publisher node will send. - */ - void initStateEvent() override; - - /** - * @brief Override polysync::Node::okStateEvent() - * Called continuously while in ok state. - */ - void okStateEvent() override; - - void releaseStateEvent() override; - - /** - * @brief Register filtered message type(s) per cmd line input. - */ - void registerFilteredMessages(); - - /** - * @brief Safely register message listeners. - * Called by registerSingle/MultipleFilteredMessages. - * - * @param std::string messageName. - */ - void tryCatchRegisterAMessageListener ( std::string ); - - /** - * @brief Extract the information from the provided message - * - * @param std::shared_ptr< Message > - variable containing the message - */ - virtual void messageEvent( std::shared_ptr< polysync::Message > message ); - - /** - * @brief Prints message(s) to external user specified file and std out. - * - * @param PolySync Message. - */ - void printToFile( std::shared_ptr < polysync:: Message > message ); - - /** - * @brief Echo PolySync message(s) on bus to standard out. - * Messages will print data, or just headers, based on cmd line input. - */ - void printMessage( std::shared_ptr < polysync:: Message > message ) const; - - /** - * @brief Calls GetOpt::optionsParse. Standardizes cmd line handling. - * - * @param argv Argument vector. - * @param argc Argument count. - * - * @return Returns true if options and option arguments are valid. - */ - bool optionsParse( const int argc, char * argv[] ); - - /** - * @brief If help -h is one of arguments, don't start node up. - * - * @return Returns true if help was requested. - */ - bool helpWasRequested() const; - - /** - * @brief Wrapper for encapsulation of the EchoHelp class. - */ - void printEchoHelpPage() const; - -private: - - /** - * @brief Get messages currently on bus and append to end of list. - * - * @return std::vector< std::string > - variable containing msg name. - */ - std::vector< std::string > getAvailableMessageNames() const; - - /** - * @brief Print messages currently available on bus, append to end of list. - * - * @param std::vector< std:: string > - variable containing msg name. - */ - void printAvailableMessage( - const std::vector< std::string > & messageTypeStrings ) const; - - /** - * Output list of message types that have been published by the current - * PolySync runtime. - * - * @note This does not print all types available in the PolySync data model. - */ - void printActiveMessageTypes() const; - - /** - * Has this node's duration, updated in the okStateEvent, reached the - * duration input from the command line (if any). - * - * @return true if time is up - */ - bool durationReached() const; - - /** - * @return Difference between start time and current time. - */ - ps_timestamp getDuration() const; - - -private: - - /** - * Magic number wrapper. One second == 1000000 micro. - */ - static constexpr ps_timestamp SecondsToMicro = 1e6; - - /** - * Manage command line input arguments. - */ - ApplicationInputHandler _inputHandler; - - /** - * Wrap notification to std::cout - */ - EchoHelp echoHelp; - - /** - * @brief Member variables to run Echo for a particular time. - * @note getTimestamp() is a PolySync function that returns message header - * timestamps in UTC microseconds. - * Start run time: see PolySyncEcho's overridden initState() function. - * Current run time: see PolySyncEcho's overridden okStateEvent() function. - */ - ps_timestamp _applicationStartTime; - - /** - * Output file stream if option set. - */ - std::ofstream _openUserFile; -}; // END polysync::EchoNode class - - -#endif // POLYSYNC_ECHO_HPP diff --git a/Echo/README.md b/Echo/README.md deleted file mode 100644 index e68cd9f..0000000 --- a/Echo/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### Echo - -This is more of a tool than an example. It is a lightweight way of printing what messages are on the bus from the command line. -The help output of this tool is very verbose and is the best way to get acquainted with its functionality. -Sometimes this tools gets bogged down with very large message types, such as `ps_lidar_points_msg`. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd Echo -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-echo -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/GroundPlaneDetection/CMakeLists.txt b/GroundPlaneDetection/CMakeLists.txt deleted file mode 100644 index 823c595..0000000 --- a/GroundPlaneDetection/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-ground-plane-detection-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - GroundPlaneDetection.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/GroundPlaneDetection/GroundPlaneDetection.cpp b/GroundPlaneDetection/GroundPlaneDetection.cpp deleted file mode 100644 index dea9541..0000000 --- a/GroundPlaneDetection/GroundPlaneDetection.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * GroundPlaneDetection.cpp - * - * Detect the ground plane from an incoming LiDAR point cloud. - * - * This application subscribes to the high level `ps_lidar_points_msg`. In the callback - * the node filters all non-ground points and republishs the data to the PolySync bus - * in another `ps_lidar_points_msg`. - * - */ - -#include -#include - - -using namespace polysync::datamodel; - - -/** - * Create a node that can publish/subscribe to the PolySync bus, - * by subclassing the PolySync C++ Node. - */ -class GroundPlaneDetection : public polysync::Node -{ - -public: - - /** - * Register this node to listen for the PolySync LidarPointsMessage - */ - void initStateEvent() override - { - // Connect messageEvent() to PolySync for the given message topic string - registerListener( getMessageTypeByName( "ps_lidar_points_msg" ) ); - } - - - /** - * First safe downcast polysync::Message to a LidarPointsMessage - * Ignore all LidarPointsMessage instances that orignated from this node - * Filter for ground points - * Publish filtered points in a new LidarPointsMessage - * - * param [in] std::shared_ptr< Message > - variable containing the incoming message - */ - virtual void messageEvent( std::shared_ptr< polysync::Message > message ) - { - if( std::shared_ptr lidarPointsMessage = - getSubclass< LidarPointsMessage >( message ) ) - { - // Filter out messages from this node - if( lidarPointsMessage->getHeaderSrcGuid() != getGuid() ) - { - publishPoints( - buildGroundPoints( lidarPointsMessage->getPoints() ) ); - } - - } - } - - /** - * Take all 3D points from a LidarPointsMessage object and return only the - * points that are near the ground plane. - * - * param [in] pointsToFilter - Full set of points from a LidarPointsMessage. - * - * return std::vector< LidarPoint > - Filtered ground plane points - */ - const std::vector< LidarPoint > buildGroundPoints( - const std::vector< LidarPoint > & pointsToFilter ) - { - std::vector< LidarPoint > groundPoints; - - for( auto point : pointsToFilter ) - { - if( pointIsNearTheGround( point.getPosition() ) ) - { - auto pos = point.getPosition(); - - // Comment the next line out to get the exact position - // Having two LiDAR sources publishing points in the exact same postiion - // causes a "flicker" in 3D rendering - pos[ 2 ] += 0.05; - - point.setPosition( pos ); - - groundPoints.push_back( point ); - } - } - - return groundPoints; - } - - /** - * Used to filter out lidar points that are not near the ground plane. - * - * param [in] point in 3D space - * - * return true if the point is near the ground, relative to the platform vehicle - */ - bool pointIsNearTheGround( const std::array< float, 3 > & point ) - { - // The vehicle origin is at the center of the rear axle, on the ground - // Incoming LiDAR point messages have been corrected for sensor mount position already - - return point[0] >= 2.5 and // x is 2.5+ meters from the vehicle origin - point[0] < 35 and // x is less than 35 meters from the vehicle origin - point[1] > -12 and // y is greater than -12 meters from the vehicle origin (towards the passenger side) - point[1] < 12 and // y is less than 12 meters from the vehicle origin (towards the driver side) - point[2] > -0.35 and // z is greater than -0.35 meters from the vehicle origin (towards the ground), - // this componsates for vehicle pitch as the vehicle drives - point[2] < 0.25; // z is less than 0.25 meters from the vehicle origin - } - - - /** - * Take a set of 3D points and publish them as a PolySync LidarPointsMessage. - * - * param [in] points std::vector of 3D points - */ - void publishPoints( - const std::vector< polysync::datamodel::LidarPoint > & points ) - { - using namespace polysync::datamodel; - - // Create a message, and set the message timestamp which represents when the data - // in this message was created, or when it originated - LidarPointsMessage groundPlaneMessage ( *this ); - - // Set the message buffer - groundPlaneMessage.setPoints( points ); - - groundPlaneMessage.setHeaderTimestamp( polysync::getTimestamp() ); - - // Publish this message instance with the ground plane points that were found - groundPlaneMessage.publish(); - } - -}; - -/** - * Entry point for this node. - * - * The "connectPolySync" method starts the node's PolySync execution loop, - * and will exit gracefully if CTRL-C is received. - * - * returns an integer exit code - */ -int main() -{ - // Create an instance of the node and connect it to the PolySync bus - GroundPlaneDetection groundPlaneNode; - - // This places the node in the initStateEvent. - groundPlaneNode.connectPolySync(); - - return 0; -} diff --git a/GroundPlaneDetection/README.md b/GroundPlaneDetection/README.md deleted file mode 100644 index b446dc1..0000000 --- a/GroundPlaneDetection/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### Echo - -This example illustrates a common process for implementing perception algorithms, and using logfile data as an algorithm development acceleration tool. - -See the [Ground Plane Detection Tutorial](https://help.polysync.io/articles/tutorials-and-examples/tutorials/ground-plane-detection-tutorial/) for a detailed description. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd Echo -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-ground-plane-detection-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/HelloWorld/CMakeLists.txt b/HelloWorld/CMakeLists.txt deleted file mode 100644 index 011b115..0000000 --- a/HelloWorld/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-helloworld-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - HelloWorld.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/HelloWorld/HelloWorld.cpp b/HelloWorld/HelloWorld.cpp deleted file mode 100644 index 7595a6b..0000000 --- a/HelloWorld/HelloWorld.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example HelloWorld.cpp - * - * PolySync Hello World C++ API example application - * Demonstrate the creation of a node and how to process node-level events - * - * Node Class definition and how to create your own Nodes - */ - -#include -#include - -using namespace std; - -/** - * @brief HellowWorldNode class - * - * The HelloWorldNode class exists to override the functions defined in the - * base class. The functions exist in the base class but are stubbed out - * and must be overloaded in order for them to do something. In this instance - * only the initStateEvent function is overloaded to demonstrate how to - * handle node events. - */ -class HelloWorldNode : public polysync::Node -{ - /** - * @brief initStateEvent - * - * Override the base class functionality to give the user an indication - * that the initialization state has been called. - * - * @param void - * @return void - */ - void initStateEvent() override - { - cout << "Hello world!" << endl; - - // Release node from PolySync exectution loop - disconnectPolySync(); - } -}; - -/** - * @brief main - * - * Entry point for this tutorial application - * The "connectPolySync" function begins the node's PolySync execution loop. - * - * @return int - exit code - */ -int main() -{ - // Create an instance of the HelloWorldNode and connect it to PolySync - HelloWorldNode helloNode; - - // When the node has been created, it will cause an initStateEvent to - // to be sent. - helloNode.connectPolySync(); - - return 0; -} diff --git a/HelloWorld/README.md b/HelloWorld/README.md deleted file mode 100644 index fe0257f..0000000 --- a/HelloWorld/README.md +++ /dev/null @@ -1,25 +0,0 @@ -### HelloWorld - -This code is part of a tutorial that demonstrates the basics of connecting to the PolySync bus. This allows you to read and write information. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd HelloWorld -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-helloworld-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/HelloWorldPublisher/CMakeLists.txt b/HelloWorldPublisher/CMakeLists.txt deleted file mode 100644 index 6628dda..0000000 --- a/HelloWorldPublisher/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-helloworld-publisher-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - HelloWorldPublisher.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/HelloWorldPublisher/HelloWorldPublisher.cpp b/HelloWorldPublisher/HelloWorldPublisher.cpp deleted file mode 100644 index 2870aa8..0000000 --- a/HelloWorldPublisher/HelloWorldPublisher.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example HelloWorldPublisher.cpp - * - * PolySync Hello World Publisher C++ API example application - * Demonstrate how to publish a message from a node - * - * Node Class definition and how to create your own Nodes - */ - -#include -#include -#include - -using namespace std; - -/** - * @brief HellowWorldPublisherNode class - * - * The HelloWorldNode class exists to override the functions defined in the - * base class. The functions exist in the base class but are stubbed out - * and must be overloaded in order for them to do something. In this instance - * only the okStateEvent function is overloaded to publish a message that the - * subscriber can receive. - */ -class HelloWorldPublisherNode : public polysync::Node -{ - /** - * @brief okStateEvent - * - * Override the base class functionality to send messages when the node - * reaches the "ok" state. This is the state where the node is in its - * normal operating mode. - * - * @param void - * @return void - */ - void okStateEvent() override - { - // Create a message - polysync::datamodel::ByteArrayMessage message( *this ); - - // Set publish time - message.setHeaderTimestamp( polysync::getTimestamp() ); - - // Populate buffer - message.setBytes( {'H', 'e', 'l', 'l', 'o', ' ', - 'W', 'o', 'r', 'l', 'd' } ); - - // Publish to the PolySync bus - message.publish(); - - // The ok state is called periodically by the system so sleep to reduce - // the number of messages sent. - polysync::sleepMicro( 1000000 ); - } -}; - -/** - * @brief main - * - * Entry point for the publisher side of this tutorial application - * The "connectToPolySync" is a blocking call, users must use Ctrl-C to exit - * this function. - * - * @return int - exit code - */ -int main() -{ - // Create an instance of the HelloWorldPublisherNode and connect it to PolySync - HelloWorldPublisherNode publisherNode; - - // When the node has been created, it will cause an initStateEvent to be - // sent and then proceed into the okState. connectToPolySync does not - // return, use Ctrl-C to exit. - publisherNode.connectPolySync(); - - return 0; -} diff --git a/HelloWorldPublisher/README.md b/HelloWorldPublisher/README.md deleted file mode 100644 index 4f20ef4..0000000 --- a/HelloWorldPublisher/README.md +++ /dev/null @@ -1,25 +0,0 @@ -### HelloWorldPublisher - -This example is the most basic C++ application you can have that publishes data to the PolySync bus. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd HelloWorldPublisher -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-helloworld-publisher-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/HelloWorldSubscriber/CMakeLists.txt b/HelloWorldSubscriber/CMakeLists.txt deleted file mode 100644 index 8506f32..0000000 --- a/HelloWorldSubscriber/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-helloworld-subscriber-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - HelloWorldSubscriber.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/HelloWorldSubscriber/HelloWorldSubscriber.cpp b/HelloWorldSubscriber/HelloWorldSubscriber.cpp deleted file mode 100644 index 0971c6e..0000000 --- a/HelloWorldSubscriber/HelloWorldSubscriber.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example HelloWorldSubscriber.cpp - * - * PolySync Hello World Subscriber C++ API example application - * Demonstrate how to subscribe a node to a message - * - */ - -#include -#include -#include - -using namespace std; - -/** - * @brief HellowWorldSubscriberNode class - * - * The HelloWorldSubscriberNode class exists to override the functions defined - * in the base Node class. The functions exist in the base class but are - * stubbed out and must be overloaded in order for them to do something. In - * this instance the initStateEvent and the messageHandlerEvent are overloaded - * to register for the messages and receive them, respectively. - */ -class HelloWorldSubscriberNode : public polysync::Node -{ -private: - ps_msg_type _messageType; - -public: - /** - * @brief initStateEvent - * - * Subscribe to a message that the publisher node will send. - * - * @param void - * @return void - */ - void initStateEvent() override - { - _messageType = getMessageTypeByName( "ps_byte_array_msg" ); - - // Register as a listener for the message type that the publisher - // is going to send. Message types are defined in later tutorials. - registerListener( _messageType ); - } - - /** - * @brief messageEvent - * - * Extract the information from the provided message - * - * @param std::shared_ptr< Message > - variable containing the message - * @return void - */ - virtual void messageEvent( std::shared_ptr< polysync::Message > message ) - { - using namespace polysync::datamodel; - if( auto byteArray = getSubclass< ByteArrayMessage >( message ) ) - { - byteArray->print(); - } - } - -}; - -/** - * @brief main - * - * Entry point for this tutorial application - * The "connectPolySync" begins this node's PolySync execution loop. - * - * @return int - exit code - */ -int main() -{ - // Create an instance of the HelloWorldNode and connect it to PolySync - HelloWorldSubscriberNode subscriberNode; - - // When the node has been created, it will cause an initStateEvent to - // to be sent. - subscriberNode.connectPolySync(); - - return 0; -} diff --git a/HelloWorldSubscriber/README.md b/HelloWorldSubscriber/README.md deleted file mode 100644 index 17cbd52..0000000 --- a/HelloWorldSubscriber/README.md +++ /dev/null @@ -1,25 +0,0 @@ -### HelloWorldSubscriber - -This example is the most basic C++ application you can have that subscribes to data through high-level messages from the PolySync bus. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd HelloWorldSubscriber -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-helloworld-subscriber-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/LogSessionExport/CMakeLists.txt b/LogSessionExport/CMakeLists.txt deleted file mode 100644 index 3101f9b..0000000 --- a/LogSessionExport/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-log-session-export-cpp ) - - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - main.cpp - LogSessionExport.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/LogSessionExport/LogSessionExport.cpp b/LogSessionExport/LogSessionExport.cpp deleted file mode 100644 index e8008cd..0000000 --- a/LogSessionExport/LogSessionExport.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2015 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include - -#include -#include -#include - -#include "LogSessionExport.hpp" - - -SessionExportExample::SessionExportExample( - int sessionId, - const std::string & sessionPath ) - : - _sessionId( sessionId ), - _sessionPath( sessionPath ), - _exporter() -{ - // Subscribe to ApplicationEventMessage to determine when - // the application connects to the PolySync bus. - connectSubscriberMethod< SessionExportExample >( - polysync::ApplicationEventMessage::getName(), - &SessionExportExample::handleEvent, - this ); - - polysync::Application::getInstance()->attachSubscriber( this ); -} - - -void SessionExportExample::handleEvent( - std::shared_ptr< polysync::Message > message ) -{ - if( auto event = polysync::datamodel::getSubclass< - polysync::ApplicationEventMessage >( message ) ) - { - if( event->getEventKind() == polysync::EventKind::Init ) - { - // This is the actual usage of the export API. - _exporter = std::unique_ptr< polysync::LogSessionExport >{ - new polysync::LogSessionExport{ - _sessionId, _sessionPath } }; - - // Export can be started with or without a progress callback. - // When complete, results will be located at - // "PSYNC_HOME/rnr_logs/export/[sessionId]" - _exporter->start( - this, - &SessionExportExample::handleTransferStatus ); - } - } -} - - -void SessionExportExample::handleTransferStatus( - const polysync::LogSessionTransferState state, - const std::shared_ptr< polysync::datamodel::FileSyncStatusMessage > & ) -{ - std::cout << "State: "; - - switch( state ) - { - case polysync::LogSessionTransferState::Invalid: - std::cout << "Invalid" << std::endl; - break; - case polysync::LogSessionTransferState::Error: - std::cout << "Error" << std::endl; - break; - case polysync::LogSessionTransferState::Initial: - std::cout << "Initial" << std::endl; - break; - case polysync::LogSessionTransferState::Enumeration: - std::cout << "Enumeration" << std::endl; - break; - case polysync::LogSessionTransferState::TransferringSystemFiles: - std::cout << "TransferringSystemFiles" << std::endl; - break; - case polysync::LogSessionTransferState::TransformingSystemFile: - std::cout << "TransformingSystemFile" << std::endl; - break; - case polysync::LogSessionTransferState::TransferringLogfiles: - std::cout << "TransferringLogfiles" << std::endl; - break; - case polysync::LogSessionTransferState::Complete: - std::cout << "Complete" << std::endl; - polysync::Application::getInstance()->disconnectPolySync(); - break; - default: - std::cout << "Unknown polysync::LogSessionTransferState" - << std::endl; - } -} diff --git a/LogSessionExport/LogSessionExport.hpp b/LogSessionExport/LogSessionExport.hpp deleted file mode 100644 index f43ea93..0000000 --- a/LogSessionExport/LogSessionExport.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2015 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -/** - * \example LogSessionExport.hpp - * - * Log session export example. - * - * Demonstrates how to use the PolySync log session transfer API to export a previously - * recorded log session from a new distributed system. - * - */ - -#ifndef LOGSESSIONEXPORT_HPP -#define LOGSESSIONEXPORT_HPP - - -#include -#include - - -class SessionExportExample : public polysync::DataSubscriber -{ - -public: - - SessionExportExample( - int sessionId, const std::string & sessionPath = {} ); - -private: - - void handleEvent( std::shared_ptr< polysync::Message > message ); - - void handleTransferStatus( - const polysync::LogSessionTransferState state, - const std::shared_ptr< polysync::datamodel::FileSyncStatusMessage > & ); - - const ps_rnr_session_id _sessionId; - - const std::string _sessionPath; - - std::unique_ptr< polysync::LogSessionExport > _exporter; - -}; - - -#endif // LOGSESSIONEXPORT_HPP - diff --git a/LogSessionExport/README.md b/LogSessionExport/README.md deleted file mode 100644 index ec48923..0000000 --- a/LogSessionExport/README.md +++ /dev/null @@ -1,25 +0,0 @@ -### LogSessionExport - -This example demonstrates how to use the PolySync Log Session Transfer API to export a recorded log session, so that it can be imported and replayed on any other PolySync system. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd LogSessionExport -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-log-session-export-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/LogSessionExport/main.cpp b/LogSessionExport/main.cpp deleted file mode 100644 index c4cdda6..0000000 --- a/LogSessionExport/main.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2015 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include - -#include - -#include "LogSessionExport.hpp" - - -int main( int argc, char * argv[] ) -{ - if( argc < 2 ) - { - std::cerr << "Usage: " << argv[0] << " [sessionId]" << std::endl; - return -1; - } - - auto sessionId = std::atoi( argv[1] ); - - std::unique_ptr< SessionExportExample > exportExample; - - if( sessionId != 0 ) - { - if( argc == 3 ) - { - exportExample = std::unique_ptr< SessionExportExample >{ - new SessionExportExample{ sessionId, argv[2] } }; - } - else - { - exportExample = std::unique_ptr< SessionExportExample >{ - new SessionExportExample{ sessionId } }; - } - } - - auto application = polysync::Application::getInstance(); - - application->setNodeName( "polysync-log-session-export-cpp" ); - - application->connectPolySync(); -} diff --git a/LogSessionImport/CMakeLists.txt b/LogSessionImport/CMakeLists.txt deleted file mode 100644 index 4c0fea3..0000000 --- a/LogSessionImport/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-log-session-import-cpp ) - - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - main.cpp - LogSessionImport.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/LogSessionImport/LogSessionImport.cpp b/LogSessionImport/LogSessionImport.cpp deleted file mode 100644 index c02079a..0000000 --- a/LogSessionImport/LogSessionImport.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2015 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include -#include - -#include "LogSessionImport.hpp" - - -SessionImportExample::SessionImportExample( const std::string & sessionPath ) - : - _sessionPath( sessionPath ), - _importer() -{ - // Subscribe to ApplicationEventMessage to determine when - // the application connects to the PolySync bus. - connectSubscriberMethod< SessionImportExample >( - polysync::ApplicationEventMessage::getName(), - &SessionImportExample::handleEvent, - this ); - - polysync::Application::getInstance()->attachSubscriber( this ); -} - - -void SessionImportExample::handleEvent( - std::shared_ptr< polysync::Message > message ) -{ - if( auto event = polysync::datamodel::getSubclass< - polysync::ApplicationEventMessage >( message ) ) - { - auto eventKind = event->getEventKind(); - - if( eventKind == polysync::EventKind::Init ) - { - // This is the actual usage of the import API. - _importer = std::unique_ptr< polysync::LogSessionImport >{ - new polysync::LogSessionImport( _sessionPath ) }; - - // - // Assign imported nodes to new destination host. - // - - // Destination hosts are specified using 'LogSessionTransferTarget'. - // The import API requires the transfer target to provide one of - // the following: - // * Interface Address String ("127.0.0.1") - // * Manager GUID (562950866709306) - // * Host's Id in the SDF - polysync::LogSessionTransferTarget transferTarget; - - for( const auto & availableNode : _importer->getAvailableNodes() ) - { - std::cout << "assigning " - << availableNode.getName() - << " to 127.0.0.1" << std::endl; - - transferTarget.setInterfaceAddress("127.0.0.1"); - - _importer->updateNodeTarget( - transferTarget, - availableNode ); - } - - // Import can be started with or without a progress callback. - // When complete, results will be located at - // "PSYNC_HOME/rnr_logs/[sessionId]" - _importer->start( - this, - &SessionImportExample::handleTransferStatus ); - } - } -} - - -void SessionImportExample::handleTransferStatus( - const polysync::LogSessionTransferState state, - const std::shared_ptr< polysync::datamodel::FileSyncStatusMessage > & ) -{ - std::cout << "State: "; - - switch( state ) - { - case polysync::LogSessionTransferState::Invalid : - std::cout << "Invalid" << std::endl; - break; - case polysync::LogSessionTransferState::Error : - std::cout << "Error" << std::endl; - break; - case polysync::LogSessionTransferState::Initial : - std::cout << "Initial" << std::endl; - break; - case polysync::LogSessionTransferState::Enumeration : - std::cout << "Enumeration" << std::endl; - break; - case polysync::LogSessionTransferState::TransferringSystemFiles : - std::cout << "TransferringSystemFiles" << std::endl; - break; - case polysync::LogSessionTransferState::TransformingSystemFile : - std::cout << "TransformingSystemFile" << std::endl; - break; - case polysync::LogSessionTransferState::TransferringLogfiles : - std::cout << "TransferringLogfiles" << std::endl; - break; - case polysync::LogSessionTransferState::Complete : - std::cout << "Complete" << std::endl; - polysync::Application::getInstance()->disconnectPolySync(); - break; - default: - std::cout << "Unknown" << std::endl; - } -} diff --git a/LogSessionImport/LogSessionImport.hpp b/LogSessionImport/LogSessionImport.hpp deleted file mode 100644 index 487b195..0000000 --- a/LogSessionImport/LogSessionImport.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2015 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example LogSessionImport.hpp - * - * Log session import example. - * - * Demonstrates how to use the PolySync log session transfer API to import a previously - * exported log session to a new distributed system. - * - */ - -#ifndef LOGSESSIONIMPORT_HPP -#define LOGSESSIONIMPORT_HPP - - -#include -#include - -#include "LogSessionImport.hpp" - - -class SessionImportExample : public polysync::DataSubscriber -{ - -public: - - SessionImportExample( const std::string & sessionPath ); - - -private: - - void handleEvent( std::shared_ptr< polysync::Message > message ); - - void handleTransferStatus( - const polysync::LogSessionTransferState status, - const std::shared_ptr< - polysync::datamodel::FileSyncStatusMessage > & statusMsg); - - const std::string _sessionPath; - - std::unique_ptr< polysync::LogSessionImport > _importer; - -}; - - -#endif // LOGSESSIONIMPORT_HPP - diff --git a/LogSessionImport/README.md b/LogSessionImport/README.md deleted file mode 100644 index 222977b..0000000 --- a/LogSessionImport/README.md +++ /dev/null @@ -1,25 +0,0 @@ -### LogSessionImport - -This example demonstrates how to use the PolySync Log Session Transfer API to import a previously exported log session to a new distributed system. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd LogSessionImport -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-log-session-import-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/LogSessionImport/main.cpp b/LogSessionImport/main.cpp deleted file mode 100644 index c97aaf0..0000000 --- a/LogSessionImport/main.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2015 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include - -#include - -#include "LogSessionImport.hpp" - - -int main( int argc, char * argv[] ) -{ - if( argc != 2 ) - { - std::cerr << "Usage: " << argv[ 0 ] << " [sessionId]" << std::endl; - return -1; - } - - SessionImportExample importExample{ argv[ 1 ] }; - - auto application = polysync::Application::getInstance(); - - application->setNodeName( "polysync-log-session-import-cpp" ); - - application->connectPolySync(); -} diff --git a/LogfileIterator/CMakeLists.txt b/LogfileIterator/CMakeLists.txt deleted file mode 100644 index 324f3cd..0000000 --- a/LogfileIterator/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-logfile-iterator-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - LogfileIteratorExample.cpp - ExampleLogfile.hpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/LogfileIterator/ExampleLogfile.hpp b/LogfileIterator/ExampleLogfile.hpp deleted file mode 100644 index 6accf9f..0000000 --- a/LogfileIterator/ExampleLogfile.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef EXAMPLELOGFILE_HPP -#define EXAMPLELOGFILE_HPP - -#include - -class ExampleLogfile : public polysync::Logfile -{ - -public: - - ExampleLogfile( polysync::Node & node ) - : - polysync::Logfile( node ) - { - // empty - } - -private: - - void readLogfileHandler( const polysync::LogfileAttributes & attributes, - ps_msg_type messageType, - const polysync::LogfileRecord & record ) override - { - // Unused arguments - static_cast< void >( attributes ); - - static_cast< void >( messageType ); - - std::cout << "readLogfileHandler" << std::endl; - - std::cout - << "log record - index: " << record.getIndex() << " - " - << "size: " << record.getSize() << " bytes - " - << "RnR timestamp (header.timestamp): " << record.getTimestamp() - << std::endl; - - auto messageRef = record.getRecordData(); - - // get the PolySync message reference - // datamodel::buildMessage( *_node, record. )->printHeader(); - - // release the resources for the - psync_message_free( _node->getNodeReference(), &messageRef ); - - // do something with the data ... - } - -}; - -#endif // EXAMPLELOGFILE_HPP diff --git a/LogfileIterator/LogfileIteratorExample.cpp b/LogfileIterator/LogfileIteratorExample.cpp deleted file mode 100644 index f18a883..0000000 --- a/LogfileIterator/LogfileIteratorExample.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example LogfileIteratorExample.cpp - * - * PolySync Logfile CPP API Iterator Example. - * - * Shows how to use the Logfile API to iterate over records in a Logfile - * outside of the normal PolySync Replay time domain. This means that the - * Logfile iterator runs as fast as the CPU will allow. - * - * @file LogfileIteratorExample.cpp - * @brief LogfileIterator Source - * - * Regarding setting node name using Logfile Iterator and how that - * relates to setFilePath(), setSessionId(), and setNodeName(): - * - * Example: in directory 1234, let a logfile be name.5678.plog, - * where 1234 = session ID, 5678 = GUID, and name = node name. - * - * To iterate over records in a logfile, use its explicit filepath. - * - * Any file specified in the path can be read from; node name is - * irrelevant when using explicit setFilePath(). - * - * How: use any setNodeName(), and use setFilePath() in - * prepareLogfileToIterate(). - */ - - -#include "LogfileIteratorExample.hpp" - -using namespace std; - - -LogfileIteratorNode::LogfileIteratorNode() - : - Node(), - _logFile( nullptr ), - _numMessagesWritten( 0 ), - _numMessagesRead( 0 ), - _messagesWereWritten( false ), - _messagesWereRead( false ), - _logFileWasIterated( false ) -{ - // empty -} - - -void LogfileIteratorNode::prepareLogfileToIterate() -{ - polysync::sleepMicro ( 1000000 ); // Sleep before mode off so queue doesn't flush. - - _logFile->setModeOff(); // Automatically disables state. - - _logFile->setFilePath( "/tmp/polysync_logfile.plog" ); - - cout << "Logfile Iterator started." << endl; -} - - -void LogfileIteratorNode::printResults() -{ - cout << "\nIterator complete.\n" - "\nReleasing logfile resources. If all messages did not print " - "to Terminal \nin either read, write, or iterator, that is due to " - "i/o (printf / cout) \nbeing slower than CPU.\n\n"; -} - - -void LogfileIteratorNode::initStateEvent() -{ - // 1. Init LogFile API resources: - _logFile = new ExampleLogfile{ *this }; - - // 2. Set up parameters. - prepareLogfileToIterate(); - - /* 3. Iterate over Logfiles in initStateEvent(), not okStateEvent(), as - * Logfile iterator operates outside of the normal Replay time domain. - */ - _logFile->readLogfile( _logFile->getFilePath() ); - - // 4. Disconnect after Iterator is done iterating over a Logfile. - disconnectPolySync(); -} - - -void LogfileIteratorNode::releaseStateEvent() -{ - printResults(); - - /* Turn off mode. Turning off the mode automatically disables state. - * Sleep before turning mode off after last write to avoid flushing of queue. - */ - polysync::sleepMicro( 5000000 ); - - _logFile->setModeOff(); - - delete _logFile; -} - - -int main() -{ - cout << "\n\n************************************************\n" - "*** PolySync LogFile API: C++ Iterator Example ***\n\n"; - - try - { - LogfileIteratorNode logfileIteratorNode; - - sleep( 2 ); - - logfileIteratorNode.setNodeName( "logfile-iterator" ); - - logfileIteratorNode.connectPolySync(); - } - catch( std::exception & e ) - { - cout<< e.what() << std::endl; - } - - return 0; -} - - diff --git a/LogfileIterator/LogfileIteratorExample.hpp b/LogfileIterator/LogfileIteratorExample.hpp deleted file mode 100644 index a2034bb..0000000 --- a/LogfileIterator/LogfileIteratorExample.hpp +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @file LogFileTestNode.hpp - * @brief PolySync Node used to test the PolySyncLogFile class functionality. - * - * PUBLIC_HEADER - */ - -#ifndef LOGFILEITERATORNODE_HPP -#define LOGFILEITERATORNODE_HPP - -#include -#include -#include - -#include "ExampleLogfile.hpp" - -class LogfileIteratorNode : public polysync::Node -{ - -public: - - /** - * @brief LogfileTestNode Empty Constructor - * Initialize private variables and call polysync::Node::Node() - * (base class constructor) - */ - LogfileIteratorNode(); - - /** - * @brief Called from initStateEvent(), this function sets up all the - * parameters needed in order to Record (write) a Logfile. - * - * @note Sets filterOutMessages() by type (optional). - * Sets filepath (optional) and Session Id. - * Sets mode to write, and enables state. - * Sets _numMessagesWritten to 0; final result printed in releaseStateEvent. - * - * @note After this function is called in initStateEvent(), fall through - * to okStateEvent() to write a single message for each okStateEvent() - * loop. - */ - void prepareLogfileToWrite(); - - /** - * @brief Called from initStateEvent(), this function sets up all the - * parameters needed in order to Replay (read) a Logfile. - * - * @note Sets filterOutMessages() by type (optional). - * Sets filepath (optional) and Session Id. - * Sets mode to write, and enables state. - * Sets _numMessagesRead to 0; final result printed in releaseStateEvent. - */ - void prepareLogfileToRead(); - - /** - * @brief called from initStateEvent(), this function sets up Logfile - * Iterator to iterate over PolySync Logfiles outside of the Replay time - * domain. That means that Mode should be set to OFF and State to Disabled. - */ - void prepareLogfileToIterate(); - - /** - * @brief Filtering messages by type in Logfile writer prevents filtered - * messages from being written to disk. Filtering messages by type in - * Logfile Reader prevents filtered messages from being published to bus. - * LogFile Reader Queue always receives messages regardless of filter. - - * @note This function calls the CPP Logfile Class' filter messages by type - * function. The first 2 params are Logfile Writer filters; the second 2 - * params are Logfile Reader filters. If you do not want to filter at all, - * do not call this function. If you call this function, set to 0 / nullptr - * whatever params you do not want to set. - */ - void filterOutMessages(); - - /** - * @brief Writes a single message for each okStateEvent() loop until - * Ctrl + C. - */ - void writeMessage(); - - /** - * @brief Reads (and dequeues) a single message for each okStateEvent() - * loop until Ctrl + C. - */ - void readDequeuedMessage(); - - /** - * @brief Prints results: if _messagesWereWritten, _numMessagesWritten. - * If _messagesWereRead, _numMessagesRead. - * If _logFileWasIterated, iterator completed. - */ - void printResults(); - -protected: - - // allocate Logfile in initstate - void initStateEvent() override; - - // called once upon disconnect. Validate here with mode. - void releaseStateEvent() override; - -private: - - ExampleLogfile * _logFile; - - int _numMessagesWritten; - - int _numMessagesRead; - - bool _messagesWereWritten; - - bool _messagesWereRead; - - bool _logFileWasIterated; - -}; // END LogFileTestNode - - -#endif // LOGFILEITERATORNODE_HPP diff --git a/LogfileIterator/README.md b/LogfileIterator/README.md deleted file mode 100644 index d55dbe2..0000000 --- a/LogfileIterator/README.md +++ /dev/null @@ -1,34 +0,0 @@ -### LogfileIterator - -This example is very powerful and very popular, and it uses the logfile API. -It allows a user to iterate over a specified logfile manually and read its contents. -A logfile iterator callback is set up, which is called every time a new “record” is popped from the logfile. -This example then prints some details from the header of each of the records. -The logfile iteration happens much faster than real time. -Be aware that a lot of people have issues with this example because they don’t realize that just because a message publishes -a message type doesn’t mean it logs that same message type. - -For example most CAN drivers log with `ps_can_frame_msg` but publish `ps_radar_targets_msg`, `ps_objects_msg`, etc. -This results in them trying to cast new logfile frames to `ps_radar_targets_msg` etc., instead of their actual format. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd LogfileIterator -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-logfile-iterator-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/LogfileQueueReader/CMakeLists.txt b/LogfileQueueReader/CMakeLists.txt deleted file mode 100644 index 1962b9d..0000000 --- a/LogfileQueueReader/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-logfile-queue-reader-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -find_package( PkgConfig REQUIRED ) - -pkg_check_modules( GLIB_PKG glib-2.0 ) - -include_directories( - . - ${PSYNC_INCLUDE_DIRS} - ${GLIB_PKG_INCLUDE_DIRS} - ) - -add_executable( ${PROJECT_NAME} - LogfileQueueReaderExample.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} - glib-2.0 -) diff --git a/LogfileQueueReader/LogfileQueueReaderExample.cpp b/LogfileQueueReader/LogfileQueueReaderExample.cpp deleted file mode 100644 index af1dad2..0000000 --- a/LogfileQueueReader/LogfileQueueReaderExample.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * Regarding setting node name using Logfile Reader and how that relates - * to setFilePath(), setSessionId(), and setNodeName(): - * - * Example: in directory 1234, let a logfile be name.5678.plog, - * where 1234 = session ID, 5678 = GUID, and name = node name. - - * To read from this logfile, you can use its filepath or its session ID. - * - * Session ID logic is default write logic. - * If you do not set explicit filepath, then directory will be timestamp - * of write time, and name will be whatever is set in setNodeName(). - * - * setFilePath() logic overrides default Session ID logic. - * For Logfile Reader, using a Logfile's explicit filepath is strongly - * recommended. - * - * Option 1: Using explicit filepath to read logfiles (recommended): - * Any file specified in the path can be read from; - * node name is irrelevant. - * How: - * 1. use any setNodeName(), then - * 2. use setFilePath() in prepareLogfileToRead(). - * - * Option 2: Using Session ID to read logfiles: - * Since reader's SDF key must match written SDF key, it's required to - * use the same node reference/context to write to, and then read from, - * a Logfile using its SessionID. Generally, that means writing to a - * Logfile and then reading from that Logfile in the same "example" - * file (same Node called from main() with connectPolySync() ). - * Doing this guarantees the same node reference, and hence, the same SDF Key. - * How: - * Not covered in this example. - * All C/C++ Logfile examples use explicit filepath, not Session ID. - */ - -/** - * \example LogfileQueueReaderExample.cpp - * - * PolySync Logfile CPP API Queue Reader Example. - * - * Shows how to use the Logfile API to read logfiles from the async queue. - * - * @file LogfileQueueReaderExample.cpp - * @brief LogfileReader Source - * - */ - - -#include - -#include "LogfileQueueReaderExample.hpp" - - -using namespace std; - - -LogfileQueueReaderNode::LogfileQueueReaderNode() - : - Node(), - _logFile( nullptr ), - _numMessagesRead( 0 ) -{ - // empty -} - -void LogfileQueueReaderNode::prepareLogfileToRead() -{ - // 1. Set path to the logfile - _logFile->setFilePath( DefaultLogfilePath ); - - _logFile->setSessionId( DefaultSessionId ); - - // 2. Enable the Replay Message Queue + get a reference to the Queue. - _logFile->enableOutputQueue( Enable ); - - // 3. Begin replay. Enqueue messages onto Replay Queue if queue valid. - _logFile->setModeRead(); - - _logFile->setStateEnabled( DefaultTimingOffset ); - - cout << "Logfile Replay started. Ctrl + C to stop, or wait until EOF." - << endl; - - // 4. Set counter. - _numMessagesRead = 0; -} - - -void LogfileQueueReaderNode::readDequeuedMessage() -{ - // Replay: dequeue a single message for each okStateEvent() loop: - ps_msg_ref dequeuedMessage = - g_async_queue_try_pop( _logFile->getReplayMessageQueue() ); - - if( dequeuedMessage != PSYNC_MSG_REF_INVALID ) - { - auto messageToPrint = - polysync::datamodel::buildMessage( *this, dequeuedMessage ); - - ++_numMessagesRead; - - cout << endl - << "Printing message # " <<_numMessagesRead <<" in queue" - << endl; - - messageToPrint->printHeader(); - } -} - - -void LogfileQueueReaderNode::initStateEvent() -{ - // 1. Init LogFile API resources: - _logFile = new polysync::Logfile{ *this }; - - // 2. Set up parameters and validate before reading in okStateEvent() loop. - prepareLogfileToRead(); - - if( _logFile->eofHasBeenReached() or not _logFile->getReplayMessageQueue() ) - { - cout << endl - << "Disconnecting: either Replay Queue invalid, or Replay EOF." - << endl; - - disconnectPolySync(); - } -} - - -void LogfileQueueReaderNode::okStateEvent() -{ - // Pop a message from the queue and output data - readDequeuedMessage(); - - if( _logFile->eofHasBeenReached() ) - { - disconnectPolySync(); - } -} - - -void LogfileQueueReaderNode::releaseStateEvent() -{ - printResults(); - - // Turn off mode. Turning off the mode automatically disables state. - // Sleep before turning mode off after last write to avoid flushing of queue. - polysync::sleepMicro( FiveSeconds ); - - _logFile->setModeOff(); - - delete _logFile; -} - - -void LogfileQueueReaderNode::printResults() -{ - cout << endl << endl - << "Read " << _numMessagesRead << " total messages." - << endl; - - if( _logFile->eofHasBeenReached() ) - { - cout << "End of file was reached." << endl; - } - else - { - cout << "End of file was not reached." << endl; - } - - cout << endl - << "*** End PolySync LogFile C++ Queue Reader Example ***" - << endl - << "*************************************************" - << endl << endl; -} - - -int main() -{ - cout << endl << endl - << "************************************************" - << endl - << "*** End PolySync C++ LogFile API: Queue Reader Example ***" - << endl << endl; - - try - { - LogfileQueueReaderNode logfileReader; - - sleep( 1 ); - - logfileReader.setNodeName( "logfile-queue-reader" ); - - logfileReader.connectPolySync(); - } - catch( std::exception & e ) - { - cout<< e.what() << std::endl; - } - - return 0; -} - diff --git a/LogfileQueueReader/LogfileQueueReaderExample.hpp b/LogfileQueueReader/LogfileQueueReaderExample.hpp deleted file mode 100644 index c953d26..0000000 --- a/LogfileQueueReader/LogfileQueueReaderExample.hpp +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @file LogfileQueueReaderExample.hpp - * - * PUBLIC_HEADER - */ - -#ifndef LOGFILEQUEUEREADERNODE_HPP -#define LOGFILEQUEUEREADERNODE_HPP - - -#include - - -// Forward declaration -namespace polysync{ - class Logfile; -} - - -/** - * @brief The LogfileQueueReaderNode class - * - * @li Implement an interface to polysync::Node - * @li Open PolySync *.plog file using the PolySync C++ Logfile API. - * @li Enable the Logfile object's message queue to receive data that has been - * extracted from the logfile. - */ -class LogfileQueueReaderNode : public polysync::Node -{ - -public: - - /** - * @brief Destructor - * - * @li Call polysync::Node::Node() -- Base class constructor - */ - LogfileQueueReaderNode(); - - /** - * @brief Default Desctructor -- Does nothing - * - * @note Dynamically allocated resources are deleted in @ref - * releaseStateEvent(); - */ - virtual ~LogfileQueueReaderNode() = default; - -protected: - - /** - * @li Set path to *.plog file - * @li Enable message queue - * @li Set Logfile mode to read - * @li Set Logfile state to enabled - */ - virtual void prepareLogfileToRead(); - - /** - * @li Dequeue PolySync message - * @li Validate dequeued message - * @li Increment message count - * @li Print message to std out - */ - virtual void readDequeuedMessage(); - - /** - * @li Output number of messages processed - * @li Notify user that end of file was reached - */ - virtual void printResults(); - - /** - * @note Called once after polysync::Node::connectPolySync() is called - * - * @li Allocate Logfile object - * @li Call @ref prepareLogfileToRead() - * @li If something went wrong, @ref polysync::Node::disconnectPolySync() - */ - virtual void initStateEvent() override; - - /** - * @note Called repeatedly during runtime - * - * @li Pop message from the queue - * @li Print message data to std out - * @li if end of logfile reached, @ref polysync::Node::disconnectPolySync() - */ - virtual void okStateEvent() override; - - /** - * @note Called once, after polysync::Node::disconnectPolySync() - * - * @li call @ref printResults() - * @li Set Logfile mode to off - * @li delete dynamically allocated memory - */ - virtual void releaseStateEvent() override; - - -protected: - - // Compile-time constants - // Default path assumes that the C or C++ Log Writer has been used. - static constexpr auto DefaultLogfilePath = "/tmp/polysync_logfile.plog"; - - static constexpr ps_timestamp FiveSeconds = 5000000; - - static constexpr ps_timestamp DefaultSessionId = 1; - - static constexpr ps_timestamp DefaultTimingOffset = 1; - - static constexpr uint Enable = 1; - - -protected: - - polysync::Logfile * _logFile; - - int _numMessagesRead; - -}; // END LogFileTestNode - - -#endif // LOGFILEQUEUEREADERNODE_HPP diff --git a/LogfileQueueReader/README.md b/LogfileQueueReader/README.md deleted file mode 100644 index 89da822..0000000 --- a/LogfileQueueReader/README.md +++ /dev/null @@ -1,32 +0,0 @@ -### LogfileQueueReader - -This example is useful when you want to access raw sensor data, just as it was sent on the wire, before the dynamic driver processes and abstracts the data. - -{{% note %}} This does not effect the functionality of the dynamic driver. It will still process and publish the high-level message types, as defined in the SDF Configurator node entry. {{% /note %}} - -You would use this node if you wanted to filter or pre-process the sensor data before it’s published to the PolySync bus. - -This is an example of a node that uses the Logfile API routines to replay a PolySync logfile using the message queue instead of subscribing to a high-level PolySync message type. -This node accesses the raw, non-abstracted `plog` data, and leverages the dynamic driver Hardware Abstraction Layer (HAL) header file to cast the raw data to low-level OEM defined C structs. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd LogfileQueueReader -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-logfile-queue-reader-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/LogfileReader/CMakeLists.txt b/LogfileReader/CMakeLists.txt deleted file mode 100644 index 468c555..0000000 --- a/LogfileReader/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-logfile-reader-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -find_package( PkgConfig REQUIRED ) - -include_directories( - . - ${PSYNC_INCLUDE_DIRS} - ) - -add_executable( ${PROJECT_NAME} - LogfileReaderExample.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} - glib-2.0 -) diff --git a/LogfileReader/LogfileReaderExample.cpp b/LogfileReader/LogfileReaderExample.cpp deleted file mode 100644 index 34d6db2..0000000 --- a/LogfileReader/LogfileReaderExample.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * - * Regarding setting node name using Logfile Reader and how that relates - * to setFilePath(), setSessionId(), and setNodeName(): - * - * Example: in directory 1234, let a logfile be name.5678.plog, - * where 1234 = session ID, 5678 = GUID, and name = node name. - - * To read from this logfile, you can use its filepath or its session ID. - * - * Session ID logic is default write logic. - * If you do not set explicit filepath, then directory will be timestamp - * of write time, and name will be whatever is set in setNodeName(). - * - * setFilePath() logic overrides default Session ID logic. - * For Logfile Reader, using a Logfile's explicit filepath is strongly - * recommended. - * - * Option 1: Using explicit filepath to read logfiles (recommended): - * Any file specified in the path can be read from; - * node name is irrelevant. - * How: - * 1. use any setNodeName(), then - * 2. use setFilePath() in prepareLogfileToRead(). - * - * Option 2: Using Session ID to read logfiles: - * Since reader's SDF key must match written SDF key, it's required to - * use the same node reference/context to write to, and then read from, - * a Logfile using its SessionID. Generally, that means writing to a - * Logfile and then reading from that Logfile in the same "example" - * file (same Node called from main() with connectPolySync() ). - * Doing this guarantees the same node reference, and hence, the same SDF Key. - * How: - * Not covered in this example. - * All C/C++ Logfile examples use explicit filepath, not Session ID. - */ - -/** - * \example LogfileQueueReaderExample.cpp - * - * PolySync Logfile CPP API Queue Reader Example. - * - * Shows how to use the Logfile API to read logfiles from the async queue. - * - * @file LogfileQueueReaderExample.cpp - * @brief LogfileReader Source - * - */ - - -#include - -#include "LogfileReaderExample.hpp" - - -using namespace std; - - -LogfileReaderNode::LogfileReaderNode() - : - Node(), - _logFile( nullptr ), - _numMessagesRead( 0 ) -{ - // empty -} - -void LogfileReaderNode::prepareLogfileToRead() -{ - // Uncomment this to demonstrate filtering out message types -// _logFile->setMessageTypeFilters( -// {}, { getMessageTypeByName( "ps_byte_array_msg" ) } ); - - // 1. Set path to the logfile - _logFile->setFilePath( DefaultLogfilePath ); - - // Session id needs to be non-zero. - _logFile->setSessionId( DefaultSessionId ); - - // 3. Begin replay. Enqueue messages onto Replay Queue if queue valid. - _logFile->setModeRead(); - - _logFile->setStateEnabled( DefaultTimingOffset ); - - cout << "Logfile Replay started. Ctrl + C to stop, or wait until EOF." - << endl; - - // 4. Set counter. - _numMessagesRead = 0; -} - - -void LogfileReaderNode::initStateEvent() -{ - // 1. Init LogFile API resources: - _logFile = new polysync::Logfile{ *this }; - - // 2. Connect to PolySync data - registerListener( getMessageTypeByName( "ps_byte_array_msg" ) ); - - // 3. Set up parameters and validate before reading in okStateEvent() loop. - prepareLogfileToRead(); - - if( _logFile->eofHasBeenReached() ) - { - cout << endl - << "Disconnecting: reached end of logfile." - << endl; - - disconnectPolySync(); - } -} - - -void LogfileReaderNode::okStateEvent() -{ - if( _logFile->eofHasBeenReached() ) - { - disconnectPolySync(); - } -} - - -void LogfileReaderNode::releaseStateEvent() -{ - printResults(); - - // Turn off mode. Turning off the mode automatically disables state. - // Sleep before turning mode off after last write to avoid flushing of queue. - polysync::sleepMicro( FiveSeconds ); - - _logFile->setModeOff(); - - delete _logFile; -} - - -void LogfileReaderNode::messageEvent( - std::shared_ptr message ) -{ - if( message ) - { - if( message->getHeaderTypeString() == "ps_byte_array_msg" ) - { - ++_numMessagesRead; - - cout << endl - << "Printing message # " <<_numMessagesRead << " in queue" - << endl; - - message->printHeader(); - } - } -} - - -void LogfileReaderNode::printResults() -{ - cout << endl << endl - << "Read " << _numMessagesRead << " total messages." - << endl; - - if( _logFile->eofHasBeenReached() ) - { - cout << "End of file was reached." << endl; - } - else - { - cout << "End of file was not reached." << endl; - } - - cout << endl - << "*** End PolySync C++ LogFile API: Reader Example ***" - << endl - << "*************************************************" - << endl << endl; -} - - - -int main() -{ - cout << endl << endl - << "************************************************" - << endl - << " *** PolySync LogFile C++ API: Reader Example *** " - << endl << endl; - - try - { - LogfileReaderNode logfileReader; - - sleep( 1 ); - - logfileReader.setNodeName( "logfile-queue-reader" ); - - logfileReader.connectPolySync(); - } - catch( std::exception & e ) - { - cout<< e.what() << std::endl; - } - - return 0; -} - diff --git a/LogfileReader/LogfileReaderExample.hpp b/LogfileReader/LogfileReaderExample.hpp deleted file mode 100644 index 79b4297..0000000 --- a/LogfileReader/LogfileReaderExample.hpp +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file LogfileReaderExample.hpp - * - * PUBLIC_HEADER - */ - -#ifndef LOGFILEQUEUEREADERNODE_HPP -#define LOGFILEQUEUEREADERNODE_HPP - - -#include - - -// Forward declaration -namespace polysync{ - class Logfile; -} - - -/** - * @brief The LogfileReaderNode class - * - * @li Implement an interface to polysync::Node - * @li Open PolySync *.plog file using the PolySync C++ Logfile API. - * @li Override polysync::Node::messageEvent() to receive data that has been - * extracted from the logfile and published to the PolySync bus via the Logfile - * API. - */ -class LogfileReaderNode : public polysync::Node -{ - -public: - - /** - * @brief Destructor - * - * @li Call polysync::Node::Node() -- Base class constructor - */ - LogfileReaderNode(); - - /** - * @brief Default Desctructor -- Does nothing - * - * @note Dynamically allocated resources are deleted in @ref - * releaseStateEvent(); - */ - virtual ~LogfileReaderNode() = default; - - -protected: - - /** - * @note Uncomment the first statement to demonstrate message filtering. - * - * @li Set path to *.plog file - * @li Set Logfile mode to read - * @li Set Logfile state to enabled - */ - virtual void prepareLogfileToRead(); - - /** - * @li Output number of messages processed - * @li Notify user that end of file was reached - */ - virtual void printResults(); - - - /** - * @note Called once after polysync::Node::connectPolySync() is called - * - * @li Allocate Logfile object - * @li Call @ref prepareLogfileToRead() - * @li If something went wrong, disconnectPolySync(); - */ - virtual void initStateEvent() override; - - /** - * @note Called repeatedly during runtime - * - * @li Print message data to std out - * @li @ref disconnectPolySync() if end of logfile has been reached - */ - virtual void okStateEvent() override; - - /** - * @note Called once, after polysync::Node::disconnectPolySync() - * - * @li call @ref printResults() - * @li Set Logfile mode to off - * @li delete dynamically allocated memory - */ - virtual void releaseStateEvent() override; - - /** - * @note Called repeatedly, any time data is available from the PolySync - * bus. - * - * @param std::shared_ptr< PolySyncMessage > - */ - virtual void messageEvent( - std::shared_ptr< polysync::Message > message ) override; - - -protected: - - // Compile-time constants - // Default path assumes that the C or C++ Log Writer has been used. - static constexpr auto DefaultLogfilePath = "/tmp/polysync_logfile.plog"; - - static constexpr ps_timestamp FiveSeconds = 5000000; - - static constexpr ps_timestamp DefaultSessionId = 1; - - static constexpr ps_timestamp DefaultTimingOffset = 1; - - static constexpr uint Enable = 1; - -protected: - - polysync::Logfile * _logFile; - - int _numMessagesRead; - -}; - - -#endif // LOGFILEQUEUEREADERNODE_HPP diff --git a/LogfileReader/README.md b/LogfileReader/README.md deleted file mode 100644 index 8586342..0000000 --- a/LogfileReader/README.md +++ /dev/null @@ -1,33 +0,0 @@ -### LogfileReader - -This example uses the Logfile API to replay a PolySync logfile `plog` file. -Even though it depends on a file in the `/tmp/` directory, it can still be easily updated to point to any existing `plog` file (the intention of the example). - /tmp/polysync_logfile.plog - -Steps to run: - - 1. Update the file `LogfileReaderExample.hpp` on line 108 to point to an existing `plog` file, (point to new rnr_logs location) - 2. Compile - 3. Run - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd LogfileReader -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-logfile-reader-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/LogfileWriter/CMakeLists.txt b/LogfileWriter/CMakeLists.txt deleted file mode 100644 index 230b89f..0000000 --- a/LogfileWriter/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-logfile-writer-cpp ) -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - LogfileWriterExample.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/LogfileWriter/LogfileWriterExample.cpp b/LogfileWriter/LogfileWriterExample.cpp deleted file mode 100644 index 0f63924..0000000 --- a/LogfileWriter/LogfileWriterExample.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Regarding setting node name using Logfile Writer and how that relates - * to setFilePath(), setSessionId(), and setNodeName() - * Example: in directory 1234, let a logfile be name.5678.plog, - * where 1234 = session ID, 5678 = GUID, and name = node name. - * - * For Logfile Writer: In prepareLogfileToWrite(), set sessionId; - * optionally, set custom filepath. If writer uses explicit - * setFilePath(), then setNodeName is irrelevant. - * - * If writer uses setSessionId() and not setFilePath(), then name of - * logfile will be set with setNodeName(), located in dir specified by - * Session Id. - */ - -/** - * \example LogfileWriterExample.cpp - * - * PolySync Logfile CPP API Writer Example. - * - * Shows how to use the Logfile API to write logfiles. - * - * @file LogfileWriterExample.cpp - * @brief LogfileWriter Source - * - */ - -#include - -#include "LogfileWriterExample.hpp" - - -using namespace std; - - -LogfileWriterNode::LogfileWriterNode() - : - Node(), - _logFile( nullptr ), - _numMessagesWritten( 0 ) -{ - // empty -} - - -void LogfileWriterNode::prepareLogfileToWrite() -{ - // 1. Set logfile file path (optional). Overrides default logic for Session ID. - _logFile->setFilePath( DefaultLogfilePath ); - - // 2. Set session ID. You can use timestamp or arbitrary name such as 1234. - _logFile->setSessionId( polysync::getTimestamp() ); - - // 3. Begin Replay: Enable state in single node context. - _logFile->setModeWrite(); - - _logFile->setStateEnabled( 0 ); - - cout << "Logfile Record started. Ctrl + C to stop." << endl; - - /* Note: Enable state in *distributed system context* uses timing now - * + offset: - * ps_timestamp stateTimingOffsetDistributedContext = - * getTimestamp() + 2000000; - * - * _logFile->setStateEnabled( stateTimingOffsetDistributedContext ); - */ - - // 4. Set counter. - _numMessagesWritten = 0; -} - - -void LogfileWriterNode::writeMessage() -{ - // Record: Write a single message for each okStateEvent() loop. - - // 1. Allocate message / fill out its parameters. - polysync::datamodel::ByteArrayMessage byteArrayMessage { *this }; - - byteArrayMessage.setBytes( { 'P','o','l','y','S','y','n','c' } ); - - byteArrayMessage.setDataType( 0 ); // index to print only every 20 messages. - - // 2. Tell user how many messages have been written so far. - ++_numMessagesWritten; - - byteArrayMessage.setDataType( _numMessagesWritten ); - - // 3. Each message written receives a unique timestamp (Replay time slicing). - byteArrayMessage.setHeaderTimestamp( polysync::getTimestamp() ); - - // 4. Write a message. Tell user how many messages have been written so far. - _logFile->writeMessage( byteArrayMessage ); - - if( _numMessagesWritten % 20 == 0 ) - { - cout << "\nLogged Message ID:" << byteArrayMessage.getDataType(); - } - - // 5. Set write frequency for "real time 1x Replay" in okState w/ sleepMicro. -} - - -void LogfileWriterNode::printResults() -{ - cout << endl << endl - << "Wrote " << _numMessagesWritten <<" total messages." - << endl - << "*** End PolySync LogFile C++ Writer Example ***" - << endl - << "*************************************************" - << endl << endl; -} - - -void LogfileWriterNode::initStateEvent() -{ - // 1. Init LogFile API resources: - _logFile = new polysync::Logfile{ *this }; - - // 2. Set up parameters before writing in okStateEvent() loop. - prepareLogfileToWrite(); - - // 3. Record (write): Write Messages until Ctrl + C in okStateEvent() loop. -} - - -void LogfileWriterNode::okStateEvent() -{ - /* For each okStateEvent() loop, process a single write + sleep (required). - * For larger messages such as Lidar, set a larger (higher) write frequency. - * Terminate with Ctrl + C. - */ - // 1. Write a message. - writeMessage(); - - // 2. Set write frequency for 1x Replay. - polysync::sleepMicro( FiveMilliSeconds ); -} - - -void LogfileWriterNode::releaseStateEvent() -{ - printResults(); - - /* Turn off mode. Turning off the mode automatically disables state. - * Sleep before turning mode off after last write to avoid flushing of queue. - * - */ - polysync::sleepMicro( FiveSeconds ); - - _logFile->setModeOff(); - - delete _logFile; -} - - -int main() -{ - cout << endl << endl - << "************************************************" - << endl - << "*** PolySync C++ LogFile API: Writer Example ***" - << endl << endl; - - try - { - LogfileWriterNode logfileWriter; - - sleep( 1 ); - - logfileWriter.setNodeName( "logfile-writer" ); - - logfileWriter.connectPolySync(); - } - catch( std::exception & e ) - { - cout << e.what() << endl; - } - - return 0; -} diff --git a/LogfileWriter/LogfileWriterExample.hpp b/LogfileWriter/LogfileWriterExample.hpp deleted file mode 100644 index 5f95e55..0000000 --- a/LogfileWriter/LogfileWriterExample.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file LogfileWriterExample.hpp - * - * PUBLIC_HEADER - */ - -#ifndef LOGFILEWRITERNODE_HPP -#define LOGFILEWRITERNODE_HPP - - -#include - - -// Forward declaration -namespace polysync{ - class Logfile; -} - - -/** - * @brief The LogfileWriterNode class - * - * @li Implement an interface to polysync::Node - * @li Open PolySync *.plog file using the PolySync C++ Logfile API. - * @li On each call to @ref okStateEvent() write a - * polysync::datamodel::ByteArrayMessage to the logfile. - */ -class LogfileWriterNode : public polysync::Node -{ - -public: - - /** - * @brief Destructor - * - * @li Call polysync::Node::Node() -- Base class constructor - */ - LogfileWriterNode(); - - - /** - * @brief Default Desctructor -- Does nothing - * - * @note Dynamically allocated resources are deleted in @ref - * releaseStateEvent(); - */ - virtual ~LogfileWriterNode() = default; - - /** - * @note Default use case is on a single machine. Uncomment statements - * provided in the source to aid with distributed hosts. - * - * @li Set path to *.plog file - * @li Set Logfile mode to read - * @li Set Logfile state to enabled - */ - virtual void prepareLogfileToWrite(); - - /** - * @li Create polysync::datamodel::ByteArrayMessage - * @li Write message to the Logfile queue - * @li Every 20 messages, notify user via std out. - */ - virtual void writeMessage(); - - /** - * @li Output number of messages processed - * @li Notify user that end of file was reached - */ - virtual void printResults(); - -protected: - - // allocate Logfile in initstate - virtual void initStateEvent() override; - - // create message and write to file, disconnect. - virtual void okStateEvent() override; - - // called once upon disconnect. Validate here with mode. - virtual void releaseStateEvent() override; - -protected: - - // Compile-time constants - // Default path assumes that the C or C++ Log Writer has been used. - static constexpr auto DefaultLogfilePath = "/tmp/polysync_logfile.plog"; - - static constexpr ps_timestamp FiveMilliSeconds = 5000; - - static constexpr ps_timestamp FiveSeconds = 5000000; - -protected: - - polysync::Logfile * _logFile; - - int _numMessagesWritten; - -}; // END LogFileTestNode - -#endif // LOGFILEWRITERNODE_HPP diff --git a/LogfileWriter/README.md b/LogfileWriter/README.md deleted file mode 100644 index 3609250..0000000 --- a/LogfileWriter/README.md +++ /dev/null @@ -1,26 +0,0 @@ -### LogfileWriter - -This is an example that uses the Logfile API to replay a PolySync logfile `plog` file. -It shows how to use the Logfile API routines to write a PolySync byte array message to a PolySync logfile `plog`. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd LogfileWriter -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-logfile-writer-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/ParameterGetSet/CMakeLists.txt b/ParameterGetSet/CMakeLists.txt deleted file mode 100644 index d1ca881..0000000 --- a/ParameterGetSet/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -cmake_minimum_required( - VERSION 2.8 - ) - -project( - polysync-parameter-get-set-cpp - ) - -add_definitions( - -std=c++11 - ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include_directories( - ${PSYNC_HOME}/include - ${PSYNC_HOME}/pdm - ${PSYNC_HOME}/include/deps/dcps/C/SAC - ${PSYNC_HOME}/include/deps/sys - ) - - -link_directories( - ${PSYNC_HOME}/lib - ) - -add_executable( - ${PROJECT_NAME} - ParameterGetSet.cpp -) - -target_link_libraries( - ${PROJECT_NAME} - polysync++ - polysync_cpp_message_support - polysync_data_model -) - diff --git a/ParameterGetSet/ParameterGetSet.cpp b/ParameterGetSet/ParameterGetSet.cpp deleted file mode 100644 index 8f939c5..0000000 --- a/ParameterGetSet/ParameterGetSet.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example ParameterGetSet.cpp - * - * Parameter Get/Set Example. - * - * Shows how to get/set parameters from the PolySync bus. Example publishes - * a single parameter message to the bus requesting all nodes parameters. - * A subscriber is created to recieve parameter messages and prints all - * data stored within the message. - * - * The example uses the standard PolySync node template and state machine. - * Send the SIGINT (control-C on the keyboard) signal to the node/process to do - * a graceful shutdown. - * - * In order to demonstrate the 'set' ability, you should define a single video-device - * node in the SDF. The example will locate and get the published image width, - * then set the active coordinate frame identifier. More importantly, it demonstrates - * the process to follow to get and set any parameter. - * - */ - -#include -#include -#include - -#include - -using namespace std; - -/** - * @brief ParameterGetSet class - * - * The ParameterGetSet class exists to override the functions defined in the - * base class. The functions exist in the base class but are stubbed out - * and must be overriden to do anything useful. In this instance - * we are overriding the main functions for sending and receiving messages as - * well as responding to error and warning events. - * - */ -class ParameterGetSet : public polysync::Node -{ -private: - const string _nodeName = "polysync-parameter-get-set-cpp"; - const string _parameterMessageName = "ps_parameters_msg"; - - ps_msg_type _messageType; - ps_guid _destGUID; - bool _setPerformed = false; - bool _setShouldBePerformed = false; - -public: - - ParameterGetSet() - { - setNodeType( PSYNC_NODE_TYPE_API_USER ); - setDomainID( PSYNC_DEFAULT_DOMAIN ); - setSDFID( PSYNC_SDF_ID_INVALID ); - setFlags( PSYNC_INIT_FLAG_STDOUT_LOGGING ); - setNodeName( _nodeName ); - } - - ~ParameterGetSet() - { - - } - - /** - * @brief initStateEvent - * - * Override the base class functionality to send messages when the node - * reaches the "init" state. This state is only called once, and will - * do two things: register listener for parameter messages and request - * all parameters from all nodes on the PolySync bus. We can print all - * incoming parameters in the message event handler - * - * @param void - * @return void - */ - - void initStateEvent() override - { - // get parameter message type - _messageType = getMessageTypeByName( _parameterMessageName ); - - // register as a listener for parameter messages that any - // node may send - // data is available in the messageEvent function below - registerListener( _messageType ); - - // set quality of service for the Parameter message type subscriber - setSubscriberReliabilityQOS( _messageType, RELIABILITY_QOS_RELIABLE ); - - // set quality of service for the Parameter message type subscriber - setPublisherReliabilityQOS( _messageType, RELIABILITY_QOS_RELIABLE ); - - } - - void releaseStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void errorStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void fatalStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void warnStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void okStateEvent() override - { - // - // create a parameter message that requests parameters from - // all active nodes on the PolySync bus - // - - // create a message - polysync::datamodel::ParametersMessage parameterMessage( *this ); - - // set message header timestamp - parameterMessage.setHeaderTimestamp( polysync::getTimestamp() ); - - // PSYNC_GUID_INVALID requests all nodes parameters, rather than a single GUID - parameterMessage.setDestGuid( PSYNC_GUID_INVALID ); - - // create a parameter which will hold the Parameter ID - polysync::datamodel::Parameter param; - - // request all parameters, rather than a single ID - param.setId( PSYNC_PARAM_ID_ALL ); - - // add our 'get all' parameter to the parameter messages list - parameterMessage.setParameters( { param } ); - - // set parameter message type to get all parameters - // you can filter for specific message types/ID's here - parameterMessage.setType( PARAMETER_MESSAGE_GET_ALL ); - - // publish to the PolySync bus - parameterMessage.publish(); - - - // - // use a parameter message to set a specific nodes parameter value - // - - // have we seen the video device on bus yet? - // the video deivce GUID is extracted from the incoming parameter message in the event handler - if( _setShouldBePerformed == true ) - { - // have we already set the value? - if( _setPerformed == false ) - { - // - _setPerformed = true; - - // - // demonstrate the 'set' operations for the IPC Parameter API - // - - // - // create a message - polysync::datamodel::ParametersMessage parameterSetMessage( *this ); - - // set message data - parameterSetMessage.setHeaderTimestamp( polysync::getTimestamp() ); - - // set the node GUID we which to receive this message - parameterSetMessage.setDestGuid( _destGUID ); - - // set parameter message type to get all parameters - // you can filter for specific message types/ID's here - // currently step, min and max are not used, though they are functional for custom use - parameterSetMessage.setType( PARAMETER_MESSAGE_SET_VALUE ); - - - // - // create a list of parameters to set - std::vector< polysync::datamodel::Parameter > parameters; - - // create a parameter and set the ID for the parameter to set the value of - polysync::datamodel::Parameter myParam; - myParam.setId( PSYNC_PARAM_ID_COORDINATE_FRAME ); - - - // - polysync::datamodel::ParameterValue paramValue; - - // set the descriminator type - // options are: unsigned long long, long long, double, and string - paramValue.setParameterValueKind( PARAMETER_VALUE_ULONGLONG ); - - // set the parameter-value value field - paramValue.setUllValue( PSYNC_COORDINATE_FRAME_PLATFORM ); - - // set the parameters value - myParam.setValue( paramValue ); - - // insert the parameter into the list - parameters.emplace_back( myParam ); - - // set the parameter list we cretaed - parameterSetMessage.setParameters( parameters ); - - // Publish to the PolySync bus - parameterSetMessage.publish(); - } - } - - // The ok state is called periodically by the system so sleep to reduce - // the number of messages sent. - polysync::sleepMicro( 1000000 ); - } - - /** - * @brief messageEvent - * - * Extract the information from the provided message by overriding the - * callback function - * - * @param std::shared_ptr< Message > - variable containing the message - * @return void - */ - void messageEvent( std::shared_ptr< polysync::Message > message ) override - { - // - // handle the newly received message - // - - using namespace polysync::datamodel; - - if( std::shared_ptr< ParametersMessage > parameterMsg = - getSubclass< ParametersMessage >( message ) ) - { - // print all parameter messages seen on the PolySync bus - //parameterMsg->print(); - - // create a list of parameters, and fill with the incoming parameter message buffer - std::vector< polysync::datamodel::Parameter > parameters = parameterMsg->getParameters(); - for( polysync::datamodel::Parameter param : parameters ) - { - // check the incoming parameter ID - if( param.getId() == PSYNC_PARAM_ID_VIDEO0_PUBLISHED_HEIGHT ) - { - // set destination GUID, which is the node that published this message - _destGUID = parameterMsg->getSourceGUID(); - if( _setPerformed == false ) - { - // should we 'set' the parameter (in the ok state) - _setShouldBePerformed = true; - } - - // extract the value from the parameter - ParameterValue width = param.getValue(); - - printf("Video device - GUID: %llu - Published image pixel width: %llu\n", _destGUID, width.getUllValue() ); - } - } - } - } - -}; - - -/** - * @brief main - * - * Entry point for this tutorial application - * The "connectToPolySync" is a blocking call, users must use Ctrl-C to exit - * this function. - * - * @param argc - int, the number of parameters on the command-line - * @param argv - char* [], the parsed command-line arguments - * - * @return int - exit code - */ -int main( int argc, char *argv[] ) -{ - // create an instance of the ParameterGetSet and connect it to - // PolySync. - ParameterGetSet parameterGetSetNode; - - // when the node has been created, it will cause an initStateEvent to be - // sent and then proceed into the okState. connectToPolySync does not - // return, use Ctrl-C to exit. - parameterGetSetNode.connectPolySync(); - - return 0; -} diff --git a/ParameterGetSet/README.md b/ParameterGetSet/README.md deleted file mode 100644 index 6373fae..0000000 --- a/ParameterGetSet/README.md +++ /dev/null @@ -1,26 +0,0 @@ -### ParameterGetSet - -This example demonstrates the logic used to filter for a specific node on the bus, and uses the ParameterGetSet API to update a specific parameter ID at runtime. -It publishes and subscribes the `ps_parameters_msg`, and checks and then updates the coordinate frame identifier, specifically for a video device node. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd ParameterGetSet -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-parameter-get-set-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/PathPlanner/CMakeLists.txt b/PathPlanner/CMakeLists.txt deleted file mode 100644 index a4f4d6a..0000000 --- a/PathPlanner/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -set( CMAKE_BUILD_TYPE "Debug" ) - -project( polysync-path-planner-algorithm-cpp ) - -project( polysync-path-planner-robot-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -find_package( OpenCV REQUIRED ) - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} - include - res -) - -add_executable( polysync-path-planner-algorithm-cpp - src/GridMap.cpp - src/Planner.cpp - SearchNode.cpp -) - -target_link_libraries( polysync-path-planner-algorithm-cpp - ${PSYNC_LIBS} - ${OpenCV_LIBS} -) - -add_executable( polysync-path-planner-robot-cpp - src/GridMap.cpp - RobotNode.cpp -) - -target_link_libraries( polysync-path-planner-robot-cpp - ${PSYNC_LIBS} - ${OpenCV_LIBS} -) diff --git a/PathPlanner/README.md b/PathPlanner/README.md deleted file mode 100644 index 4f4f65a..0000000 --- a/PathPlanner/README.md +++ /dev/null @@ -1,32 +0,0 @@ -### PathPlanner - -This is a C++ algorithm example. -This example will build a basic path planner algorithm in PolySync. We will apply a basic A\* planner to a simulated search space, generate the optimal path to the goal state, and then move a simulated robot along that path to the goal. The optimal path is sent one waypoint at a time as a `PlatformMotionMessage`, which is defined in the [C++ Sensor Data Model](http://polysync.github.io/Docs-2.0/#platformmotionmessage) Module. - -For a detailed description, see: [Path Planner Tutorial](https://help.polysync.io/articles/tutorials-and-examples/tutorials/path-planner-tutorial/). - -### Dependencies - -[OpenCV for Linux/Mac - Version 2.4.13](https://github.com/Itseez/opencv/archive/2.4.13.zip) - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install -``` - -### Building and running the node - -```bash -$ cd PathPlanner -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-path-planner-robot-cpp -# In another terminal window, run the planner node -$ ./polysync-path-planner-algorithm-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/PathPlanner/RobotNode.cpp b/PathPlanner/RobotNode.cpp deleted file mode 100644 index 00f21e1..0000000 --- a/PathPlanner/RobotNode.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include - -#include "RobotNode.hpp" - -using namespace cv; -using namespace std; -using namespace polysync::datamodel; - -constexpr int INVALID_LOC = -1; - -/** - * \example RobotNode.cpp - * - * PolySync Path Planner Example. - * - * Shows how to subscribe a simulated robot node to a planning algorithm node. - * Robot node listens for platform motion messages with desired waypoints from - * planner algorithm. Specifically, each platform motion message has a position - * and an orientation. The incoming position fields give the current waypoint - * number and total number of waypoints. The incoming orientation fields give - * the x and y axis coordinate that the robot should move to. Robot moves to - * the new position and reports back its new location. - * - * @file RobotNode.cpp - * @brief RobotNode Source - * - */ -RobotNode::RobotNode( ) - : - _world( ), - _golLocX( INVALID_LOC ), - _golLocY( INVALID_LOC ), - _newRobLocX( INVALID_LOC ), - _newRobLocY( INVALID_LOC ), - _numWaypoints( INVALID_LOC ), - _waypointCounter( 0 ) -{ - setNodeName( "robotNode" ); -} - -RobotNode::~RobotNode( ) -{ -} - -/** - * @brief initStateEvent - * - * The initStateEvent is triggered once when this node is initialized in - * PolySync. This is a good place to initialize variables dependant on a - * polysync::Node reference. - * - */ -void RobotNode::initStateEvent( ) -{ - - // register node as a subscriber to platform motion messages from ANY node. - registerListener( getMessageTypeByName( "ps_platform_motion_msg" ) ); - - setSubscriberReliabilityQOS( - getMessageTypeByName( "ps_platform_motion_msg" ), - RELIABILITY_QOS_RELIABLE ); -} - -/** - * @brief okStateEvent - * - * Override the base class functionality to send messages when the node - * reaches the "ok" state. This is the state where the node is in its - * normal operating mode. - * - */ -void RobotNode::okStateEvent( ) -{ - - // wait for a goal location message from searchNode to be received - if ( _golLocX == INVALID_LOC || _golLocY == INVALID_LOC ) - { - - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro(10000); - return; - - } - - // when goal received, generate a map with that goal state. - else if ( _newRobLocX == INVALID_LOC || _newRobLocY == INVALID_LOC ) - { - - cout << endl << "Goal location received by robot."; - cout << endl << "Generating map - - - - - - > " << std::flush; - - _world = std::unique_ptr< GridMap >{ new GridMap }; - - // pass in goal location - _world->generateMap( _golLocX, _golLocY ); - - _newRobLocX = _world->robLoc[0][0]; - _newRobLocY = _world->robLoc[0][1]; - - cout << "Map generated. " << endl; - cout << "Sending robot start location to planner algorithm." << endl; - cout << endl << "RobotNode waiting for waypoints." << endl; - - } - - // with map generated, begin sending location messages to searchNode - else if ( _golLocX != INVALID_LOC && _golLocY != INVALID_LOC ) - { - - sendLocationToPlanner( ); - - // have I recieved the final waypoint? if so, ask the user to shut down - if ( _waypointCounter == _numWaypoints - 2) - { - cout << endl << "Robot is at goal state after "; - cout << _waypointCounter << " waypoints. " << endl << endl; - cout << "Press return key or Ctrl-C to shut down RobotNode."; - cout << endl; - - cin.get(); - cout << endl << "Shutting down RobotNode." << endl << endl; - - disconnectPolySync( ); - - return; - } - - // The ok state is called periodically by the system so sleep to reduce - // the number of messages sent. do nothing, sleep for 1 millisecond. - polysync::sleepMicro(1000); - - } - - else - { - - // do nothing, sleep for 100 milliseconds - polysync::sleepMicro(100000); - return; - - } -} - -/** - * @brief messageEvent - * - * Extract the information from the provided message - * - * @param std::shared_ptr< Message > - variable containing the message - */ -void RobotNode::messageEvent( std::shared_ptr< polysync::Message > newMsg ) -{ - - // check whether new message is not your own. This check is only important - // since robotNode and searchNode both publish and subscribe to messages. - if ( newMsg->getHeaderSrcGuid( ) == getGuid( ) ) - { - return; - } - - // now check whether new message is a PlatformMotionMessage. - if ( auto msg = getSubclass< PlatformMotionMessage >( newMsg ) ) - { - - // the first received message from searchNode will be the goal location. - if ( _golLocX == INVALID_LOC && _golLocY == INVALID_LOC ) - { - _golLocX = msg->getOrientation()[0]; - _golLocY = msg->getOrientation()[1]; - } - - // discard any received messages still containing the goal location - else if ( msg->getOrientation()[0] == _golLocX && - msg->getOrientation()[1] == _golLocY ) - { - return; - } - - // if a new waypoint, send it to the robot and move to the new location. - else if ( msg->getPosition()[0] > _waypointCounter ) - { - _waypointCounter = msg->getPosition()[0]; - _numWaypoints = msg->getPosition()[2]; - - _newRobLocX = msg->getOrientation()[0]; - _newRobLocY = msg->getOrientation()[1]; - - cout << "Received waypoint " << _waypointCounter; - cout << " from Planner. X = " << _newRobLocX << ", Y = "; - cout << _newRobLocY << endl << std::flush; - } - } -} - -/** - * @brief sendLocationToPlanner - * - * Move robot to new desired location and report back current position. - * - * @return int - GridMap index of robot's new position. - */ -void RobotNode::sendLocationToPlanner( ) -{ - - _world->moveRobot( _newRobLocX, _newRobLocY ); - - double actualRobLocX = double( _world->robLoc[0][0] ); - double actualRobLocY = double( _world->robLoc[0][1] ); - - // Create a message - PlatformMotionMessage msg( *this ); - - // Set publish time - msg.setHeaderTimestamp( polysync::getTimestamp() ); - - // Populate buffer - msg.setPosition( { double( _waypointCounter ), 0, 0 } ); - msg.setOrientation( { actualRobLocX, actualRobLocY, 0, 0 } ); - - // Publish to the PolySync bus - msg.publish(); - -} - -/** - * Entry point for the RobotNode (platform) side of this tutorial application. - * The node will receive waypoints by the planner algorithm and move to the - * desired position. The "connectPolySync" is a blocking call, users must - * use Ctrl-C to exit this function. - */ - -int main( ) -{ - - RobotNode robotNode; - robotNode.connectPolySync( ); - - return 0; -} diff --git a/PathPlanner/SearchNode.cpp b/PathPlanner/SearchNode.cpp deleted file mode 100644 index b6f1b60..0000000 --- a/PathPlanner/SearchNode.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include - -#include "SearchNode.hpp" -#include "GridMap.hpp" - -using namespace cv; -using namespace std; -using namespace polysync::datamodel; - -constexpr int INVALID_LOC = -1; - -/** - * \example SearchNode.cpp - * - * PolySync Path Planner Example. - * - * Shows how to subscribe a simulated planning algorithm node to a simulated - * robot node. Search node finds the optimal path from a start location to a - * generated goal location. Then the node sends the optimal path one waypoint - * at a time in the form of platform motion messages. Specifically, each - * platform motion message has a position and an orientation. The outgoing - * position fields give the current waypoint number and total number of - * waypoints. The outgoing orientation fields give the x and y axis coordinate - * that the robot should move to. - * - * @file SearchNode.cpp - * @brief SearchNode Source - * - */ -SearchNode::SearchNode( ) - : - _searcher( ), - _golLocX( INVALID_LOC ), - _golLocY( INVALID_LOC ), - _robLocX( INVALID_LOC ), - _robLocY( INVALID_LOC ), - _newRobLocX( INVALID_LOC ), - _newRobLocY( INVALID_LOC ), - _numWaypoints( INVALID_LOC ), - _waypointCounter( INVALID_LOC ) -{ - setNodeName( "searchNode" ); - - setNodeType( PSYNC_NODE_TYPE_SOFTWARE_ALGORITHM ); -} - -SearchNode::~SearchNode( ) -{ -} - -/** - * @brief initStateEvent - * - * The initStateEvent is triggered once when this node is initialized in - * PolySync. This is a good place to initialize variables dependant on a - * polysync::Node reference. - * - */ -void SearchNode::initStateEvent( ) -{ - - // register node as a subscriber to platform motion messages from ANY node. - registerListener( getMessageTypeByName( "ps_platform_motion_msg" ) ); - - setSubscriberReliabilityQOS( - getMessageTypeByName( "ps_platform_motion_msg" ), - RELIABILITY_QOS_RELIABLE ); -} - -/** - * @brief okStateEvent - * - * Override the base class functionality to send messages when the node - * reaches the "ok" state. This is the state where the node is in its - * normal operating mode. - * - */ -void SearchNode::okStateEvent( ) -{ - - // generate goal state at a pseudo-random location. - if ( _golLocX == INVALID_LOC && _golLocY == INVALID_LOC ) - { - - _searcher = std::unique_ptr< Planner >{ new Planner }; - - _golLocX = _searcher->getGoalX( ); - _golLocY = _searcher->getGoalY( ); - - cout << endl << "Goal Location generated by Planner Algorithm. "; - cout << endl << "Sending goal location to robot." << endl << endl; - cout << "Waiting for Robot Location." << endl << endl << std::flush; - - } - - // send goal location to robot repeatedly until it is received. - else if ( _robLocX == INVALID_LOC || _robLocY == INVALID_LOC ) - { - - sendGoalToRobot( ); - - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro(10000); - - } - - // once robot reports its starting location, search the space for the - // optimal path from start to goal state. - else if ( _newRobLocX == INVALID_LOC && _newRobLocY == INVALID_LOC ) - { - - cout << "Robot start location received by planner algorithm." << endl; - cout << "Begin searching for optimal path from start location." << endl; - - int robIndex = _searcher->world.getIndexFromState( _robLocX, _robLocY) ; - - // use A* search to find optimal path. - _numWaypoints = _searcher->searchAStar( robIndex ); - - _newRobLocX = int(_robLocX); - _newRobLocY = int(_robLocY); - - } - - // wait until done searching, then send out next waypoint. - else if ( _newRobLocX != INVALID_LOC || _newRobLocY != INVALID_LOC ) - { - - // have I sent the final waypoint? if so, shut down - if ( _waypointCounter == _numWaypoints - 2 ) - { - cout << endl << "Robot arrived at goal state after "; - cout << _waypointCounter << " waypoints. " << endl; - cout << "Shutting down SearchNode." << endl << endl; - - disconnectPolySync( ); - - return; - } - - cout << "Sending waypoint " << _waypointCounter + 1 << " to robot."; - cout << endl; - - int newIndex = _searcher->getNextWaypoint( _waypointCounter + 1 ); - - sendNextWaypoint( newIndex, int(_waypointCounter + 1) ); - - // The ok state is called periodically by the system so sleep to reduce - // the number of messages sent. do nothing, sleep for 1 millisecond. - polysync::sleepMicro(1000); - - } - - else - { - - // do nothing, sleep for 100 milliseconds - polysync::sleepMicro(100000); - return; - - } -} - -/** - * @brief messageEvent - * - * Extract the information from the provided message - * - * @param std::shared_ptr< Message > - variable containing the message - */ -void SearchNode::messageEvent( std::shared_ptr< polysync::Message > newMsg ) -{ - - // check whether new message is not your own. This check is only important - // since robotNode and searchNode both publish and subscribe to messages. - if ( newMsg->getHeaderSrcGuid( ) == getGuid( ) ) - { - return; - } - - // now check whether new message is a PlatformMotionMessage. - if ( auto msg = getSubclass< PlatformMotionMessage >( newMsg ) ) - { - - // all received platform motion messages will be current robot location. - // robot will also report back last waypoint received so planner can - // send the next waypoint. - if ( msg->getOrientation()[0] != _robLocX || - msg->getOrientation()[1] != _robLocY ) - { - _robLocX = msg->getOrientation()[0]; - _robLocY = msg->getOrientation()[1]; - - if ( _waypointCounter != INVALID_LOC ) - { - cout << "New Robot Location Message received at waypoint: "; - cout << msg->getPosition()[0] << endl << std::flush; - } - _waypointCounter = msg->getPosition()[0]; - } - } -} - -/** - * @brief sendGoalToRobot - * - * SearchNode reports goal location so that RobotNode can render the GridMap. - * - */ -void SearchNode::sendGoalToRobot( ) -{ - - // Create a message - PlatformMotionMessage msg( *this ); - - // Set publish time - msg.setHeaderTimestamp( polysync::getTimestamp() ); - - // Populate buffer - msg.setOrientation( { double(_golLocX), double(_golLocY), 0, 0 } ); - - // Publish to the PolySync bus - msg.publish( ); - -} - -/** - * @brief sendNextWaypoint - * - * Receive current robot location and send the next waypoint from there. - * - * @param int, int - index of new position, # of waypoint at that position - */ -void SearchNode::sendNextWaypoint( int newIndex, int waypointID ) -{ - - _searcher->world.getStateFromIndex( newIndex ); - _newRobLocX = _searcher->world.checkedMoveIndX; - _newRobLocY = _searcher->world.checkedMoveIndY; - - // Create a message - PlatformMotionMessage msg( *this ); - - // Set publish time - msg.setHeaderTimestamp( polysync::getTimestamp() ); - - // Populate buffer - msg.setPosition( { double( waypointID ), 0, double( _numWaypoints ) } ); - msg.setOrientation( { double(_newRobLocX), double(_newRobLocY), 0, 0 } ); - - // Publish to the PolySync bus - msg.publish(); - -} - -/** - * Entry point for the SearchNode (planner) side of this tutorial application. - * The node will search the map and generate a set waypoints to send to the - * robot node. The "connectPolySync" is a blocking call, users must use Ctrl-C - * to exit this function. - */ - -int main() -{ - - SearchNode searchNode; - searchNode.connectPolySync( ); - - return 0; -} diff --git a/PathPlanner/include/GridMap.hpp b/PathPlanner/include/GridMap.hpp deleted file mode 100644 index 0284752..0000000 --- a/PathPlanner/include/GridMap.hpp +++ /dev/null @@ -1,90 +0,0 @@ -//GridMap.hpp -#ifndef GRIDMAP_HPP -#define GRIDMAP_HPP - -#include - - -using namespace cv; -using namespace std; - - -class GridMap -{ - -public: - - GridMap( ); - - ~GridMap( ); - - void generateMap( ); - - void generateMap( int x, int y ); - - void moveRobot( int x, int y ); - - bool checkGoal( int index ); - - bool checkMove( int index, int size ); - - int getIndexFromState( int x, int y ); - - void getStateFromIndex( int index ); - - -public: - - Mat map; - - int nRows{ 500 }; - - int nCols{ 500 }; - - int robSize{ 29 }; - - int robLoc[4][2]; - - int golLoc[4][2]; - - int checkedMoveIndX; - - int checkedMoveIndY; - - -private: - - void generateRobot( ); - - void generateGoal( ); - - void generateGoal( int x, int y ); - - void fillQuad(int ( &location )[ 4 ][ 2 ], int size); - - void showMap( ); - - void updateMap( ); - - bool checkHit( int x, int y, int size ); - - -private: - - Mat _robot; - - Mat _gol; - - Mat _staticMap; - - Mat _pathMap; - - string _mapID{ "../res/maze2.pgm" }; - - string _robID{ "../res/robot.jpg" }; - - string _golID{ "../res/gold.jpg" }; - -}; - -#endif // GRIDMAP_HPP diff --git a/PathPlanner/include/Planner.hpp b/PathPlanner/include/Planner.hpp deleted file mode 100644 index c71db44..0000000 --- a/PathPlanner/include/Planner.hpp +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef PLANNER_HPP -#define PLANNER_HPP - -#include "GridMap.hpp" - - -class Planner -{ - -public: - - Planner( ); - - ~Planner( ); - - int searchAStar( int startLoc ); - - void plotOptimalPath( ); - - int getGoalX( ); - - int getGoalY( ); - - int getNextWaypoint( int index ); - - int getPathSize( ); - - -public: - - GridMap world; - - std::vector< std::vector< int > > path; - - -private: - - void initializeSearchSpace( ); - - int getSearchNode( ); - - void getNeighbors( int index ); - - -private: - - std::vector< int > _searchMap; - - std::vector< float > _heuristic; - - std::vector< float > _globalScore; - - std::vector< float > _pathScore; - - float _epsilon{ 2 }; - - bool _endGame{ false }; - - int _curLoc; - - int _newLoc; - - std::vector< std::vector< int > > _moves; - - std::array< int, 8 > _tempMoves; - - std::vector< int > _closedSet; - - std::vector< int > _openSet; - - int _expandedNodes{ 1 }; - -}; - -#endif // PLANNER_HPP diff --git a/PathPlanner/include/RobotNode.hpp b/PathPlanner/include/RobotNode.hpp deleted file mode 100644 index 3a585ca..0000000 --- a/PathPlanner/include/RobotNode.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef ROBOTNODE_HPP -#define ROBOTNODE_HPP - -#include - -#include - -#include "GridMap.hpp" - - -using namespace cv; -using namespace std; - - -class RobotNode : public polysync::Node -{ - -public: - - RobotNode( ); - - ~RobotNode( ); - - -private: - - virtual void initStateEvent( ) override; - - virtual void okStateEvent( ) override; - - virtual void messageEvent( std::shared_ptr< polysync::Message > ) override; - - virtual void sendLocationToPlanner( ); - - -private: - - std::unique_ptr< GridMap > _world; - - std::atomic_int _golLocX; - - std::atomic_int _golLocY; - - std::atomic_int _newRobLocX; - - std::atomic_int _newRobLocY; - - std::atomic_int _numWaypoints; - - std::atomic_int _waypointCounter; - -}; - -#endif //ROBOTNODE_HPP diff --git a/PathPlanner/include/SearchNode.hpp b/PathPlanner/include/SearchNode.hpp deleted file mode 100644 index 4fa3656..0000000 --- a/PathPlanner/include/SearchNode.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef SEARCHNODE_HPP -#define SEARCHNODE_HPP - -#include - -#include - -#include "Planner.hpp" - - -using namespace cv; -using namespace std; - - -class SearchNode : public polysync::Node -{ - -public: - - SearchNode( ); - - ~SearchNode( ); - - -private: - - virtual void initStateEvent( ) override; - - virtual void okStateEvent( ) override; - - virtual void messageEvent( std::shared_ptr< polysync::Message > ) override; - - virtual void sendGoalToRobot( ); - - virtual void sendNextWaypoint( int waypointIndex, int waypointID ); - - -private: - - std::unique_ptr< Planner > _searcher; - - std::atomic_int _golLocX; - - std::atomic_int _golLocY; - - std::atomic_int _robLocX; - - std::atomic_int _robLocY; - - std::atomic_int _newRobLocX; - - std::atomic_int _newRobLocY; - - std::atomic_int _numWaypoints; - - std::atomic_int _waypointCounter; - -}; - -#endif //SEARCHNODE_HPP diff --git a/PathPlanner/res/gold.jpg b/PathPlanner/res/gold.jpg deleted file mode 100644 index b4ffcac..0000000 Binary files a/PathPlanner/res/gold.jpg and /dev/null differ diff --git a/PathPlanner/res/maze2.pgm b/PathPlanner/res/maze2.pgm deleted file mode 100644 index 0c3812d..0000000 Binary files a/PathPlanner/res/maze2.pgm and /dev/null differ diff --git a/PathPlanner/res/robot.jpg b/PathPlanner/res/robot.jpg deleted file mode 100644 index 9698e4f..0000000 Binary files a/PathPlanner/res/robot.jpg and /dev/null differ diff --git a/PathPlanner/src/GridMap.cpp b/PathPlanner/src/GridMap.cpp deleted file mode 100644 index 7febdde..0000000 --- a/PathPlanner/src/GridMap.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include - -#include -#include - -#include "GridMap.hpp" - -using namespace cv; -using namespace std; - -/** - * \example GridMap.cpp - * - * PolySync Path Planner Example. - * - * Render a map with goal and _gol locations. Check goals and legal moves by - * comparing pixel color at a given cell. Requires openCV - * - * @file GridMap.cpp - * @brief GridMap Source - * - */ -GridMap::GridMap( ) -{ - - srand(time(NULL)); - -} - -GridMap::~GridMap( ) { - -} - -/** - * @brief generateMap - * - * Overloaded function to read in an image file and generate a working map. Goal - * generated randomly. - * - */ -void GridMap::generateMap( ) -{ - - map = imread( _mapID, CV_LOAD_IMAGE_COLOR ); - - resize( map, map, Size( nRows, nCols ) ); - - threshold( map, map, 254.9, 255, THRESH_BINARY ); - - if( !map.data ) - { - printf( "Error loading src \n" ); - - return; - } - - generateGoal( ); - - _staticMap = map.clone(); - _pathMap = map.clone(); - - generateRobot( ); - -} - -/** - * @brief generateMap - * - * Overloaded function to read in an image file and generate a working map. Goal - * generated at a specific location. - * - * @param int, int - x and y coordinates of desired goal location. - */ -void GridMap::generateMap( int x, int y ) -{ - - map = imread( _mapID, CV_LOAD_IMAGE_COLOR ); - - resize( map, map, Size( nRows, nCols ) ); - - threshold( map, map, 254.9, 255, THRESH_BINARY ); - - if( !map.data ) - { - printf( "Error loading src \n" ); - - return; - } - - generateGoal( x, y ); - - _staticMap = map.clone(); - _pathMap = map.clone(); - - generateRobot( ); - - showMap( ); - -} - -/** - * @brief generateRobot - * - * Read in an image file and generate a working robot instance. - * - */ -void GridMap::generateRobot( ) -{ - - _robot = imread( _robID, CV_LOAD_IMAGE_COLOR ); - - resize( _robot, _robot, Size( robSize, robSize ) ); - - robLoc[ 0 ][ 0 ] = nCols - robSize - 1; - robLoc[ 0 ][ 1 ] = nRows - robSize - 1; - - fillQuad( robLoc, robSize ); - - _robot.copyTo( map( cv::Rect( robLoc[ 0 ][ 0 ], - robLoc[ 0 ][ 1 ], - robSize, - robSize ) ) ); - -} - -/** - * @brief generateGoal - * - * Overloaded function to generate a working goal state at a pseudo-random - * position. - * - */ -void GridMap::generateGoal( ) -{ - - _gol = imread( _golID, CV_LOAD_IMAGE_COLOR ); - - resize( _gol, _gol, Size( robSize, robSize ) ); - - golLoc[ 0 ][ 0 ] = rand() % 50 + 150; - golLoc[ 0 ][ 1 ] = rand() % 50 + 1; - - fillQuad( golLoc, robSize ); - - _gol.copyTo( map( cv::Rect( golLoc[ 0 ][ 0 ], - golLoc[ 0 ][ 1 ], - robSize, - robSize ) ) ); - -} - -/** - * @brief generateGoal - * - * Overloaded function to generate a working goal state at a specific location. - * - * @param int, int - x and y coordinates of desired goal location. - */ -void GridMap::generateGoal( int x, int y ) -{ - - _gol = imread( _golID, CV_LOAD_IMAGE_COLOR ); - - resize( _gol, _gol, Size( robSize, robSize ) ); - - golLoc[ 0 ][ 0 ] = x; - golLoc[ 0 ][ 1 ] = y; - - fillQuad( golLoc, robSize ); - - _gol.copyTo( map( cv::Rect( golLoc[ 0 ][ 0 ], - golLoc[ 0 ][ 1 ], - robSize, - robSize ) ) ); - -} - -/** - * @brief moveRobot - * - * Move robot icon and location array to new location - * - * @param int, int - x and y coordinates of desired robot location. - */ -void GridMap::moveRobot( int x, int y ) -{ - - bool hit = checkHit( x, y, robSize ); - - if ( hit == false ) - { - - robLoc[ 0 ][ 0 ] = x; - robLoc[ 0 ][ 1 ] = y; - - fillQuad( robLoc, robSize ); - - updateMap( ); - - } - - else - { - return; - } - - checkGoal( getIndexFromState( robLoc[ 0 ][ 0 ], robLoc[ 0 ][ 1 ] ) ); - -} - -/** - * @brief fillQuad - * - * Populate corners of icon using its size as delimiter. This is used to check - * hit, goal, or error conditions. - * - * @param int[4][2], int - location of upper left corner, icon size - */ -void GridMap::fillQuad( int ( &location )[ 4 ][ 2 ], int size ) -{ - - location[ 1 ][ 0 ] = location[ 0 ][ 0 ] + size; - - location[ 1 ][ 1 ] = location[ 0 ][ 1 ]; - - location[ 2 ][ 0 ] = location[ 0 ][ 0 ]; - - location[ 2 ][ 1 ] = location[ 0 ][ 1 ] + size; - - location[ 3 ][ 0 ] = location[ 1 ][ 0 ]; - - location[ 3 ][ 1 ] = location[ 2 ][ 1 ]; - -} - -/** - * @brief showMap - * - * Clear current map render, populate current robot, query location, show image - * - */ -void GridMap::showMap( ) -{ - - map = _staticMap.clone( ); - - _robot.copyTo( map( cv::Rect( robLoc[ 0 ][ 0 ], - robLoc[ 0 ][ 1 ], - robSize, - robSize ) ) ); - - imshow( "PolySync Path Planner Example", map ); - - waitKey( 50 ); - -} - -/** - * @brief updateMap - * - * Clear current map render, populate current robot, query location, add the - * current location as a grey dot (write a path), show image - * - */ -void GridMap::updateMap( ) -{ - - int xCenter = int( floor( robLoc[ 0 ][ 0 ] + ( robSize / 2 ) ) ); - int yCenter = int( floor( robLoc[ 0 ][ 1 ] + ( robSize / 2 ) ) ); - - map = _pathMap.clone(); - - _pathMap.at< uchar >( Point( 3 * xCenter - 1, yCenter ) ) = 0; - - _robot.copyTo( map( cv::Rect( robLoc[ 0 ][ 0 ], - robLoc[ 0 ][ 1 ], - robSize, - robSize ) ) ); - - imshow( "PolySync Path Planner Example", map ); - - waitKey( 1 ); - -} - -/** - * @brief checkHit - * - * check corners of icon location for out of bounds, or illegal hit - * - * @param int, int, int - x, y coordinate of upper left corner, icon size - */ -bool GridMap::checkHit( int x, int y, int size ) -{ - - int tempLoc[ 4 ][ 2 ]{ x, y, 0, 0, 0, 0, 0, 0 }; - - fillQuad( tempLoc, size ); - - for ( int i = 0; i < 4; i++ ) - { - if (map.at< uchar >( Point( 3 * tempLoc[ i ][ 0 ], - tempLoc[ i ][ 1 ] ) ) == 0 ) - { - - return true; - - } - - else if ( tempLoc[ i ][ 0 ] < 0 || tempLoc[ i ][ 1 ] < 0 || - tempLoc[ i ][ 0 ] >= nCols || tempLoc[ i ][ 1 ] >= nRows ) - { - - return true; - - } - - } - - return false; - -} - -/** - * @brief checkGoal - * - * check whether index is at the goal state - * - * @param int - index of current position - */ -bool GridMap::checkGoal( int index ) -{ - - getStateFromIndex( index ); - - if( abs( checkedMoveIndX - golLoc[ 0 ][ 0 ] ) <= robSize - 1 && - abs( checkedMoveIndY - golLoc[ 0 ][ 1 ] ) <= robSize - 1 ) - { - - return true; - - } - - return false; - -} - -/** - * @brief checkMove - * - * Easier access to checkHit by passing index - * - * @param int, int - index of current position, icon size - */ -bool GridMap::checkMove( int index, int size ) -{ - - getStateFromIndex( index ); - - if ( !checkHit( checkedMoveIndX, checkedMoveIndY, size ) ) - { - - return true; - - } - - return false; - -} - -/** - * @brief getIndexFromState - * - * return index from x and y coordinates - * - * @param int, int - x and y map coordinates - * @return int - index at x and y coordinates - */ -int GridMap::getIndexFromState( int x, int y ) -{ - - return int( y * nRows + x ); - -} - -/** - * @brief getStateFromIndex - * - * return x and y coordinates from index. Accessed by public variable. - * - * @param int - index at x and y coordinates - * @return int, int - x and y map coordinates - */ -void GridMap::getStateFromIndex( int index ) -{ - - checkedMoveIndX = index % nRows; - checkedMoveIndY = index / nCols; - - return; - -} diff --git a/PathPlanner/src/Planner.cpp b/PathPlanner/src/Planner.cpp deleted file mode 100644 index 51ab5b0..0000000 --- a/PathPlanner/src/Planner.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include - - -#include "Planner.hpp" - -using namespace std; - -/** - * \example Planner.cpp - * - * PolySync Path Planner Example. - * - * Use A* Search to find the optimal path to the goal location. This is a class - * that SearchNode uses. Once searchAStar() is called, SearchNode sends the - * next waypoint in path vector until the robot is at the goal state. - * - * @file Planner.cpp - * @brief Planner Source - * - */ -Planner::Planner( ) - : - world( ), - path( ) -{ - world.generateMap( ); - - initializeSearchSpace( ); -} - -/** - * @brief initializeSearchSpace - * - * Initialize vectors needed to perform A* search. searchMap is a vector which - * stores '0' or '255' at each index, signifying whether that cell is black or - * white. heuristic is a vector storing the Euclidean distance from the goal - * state. globalScore is a vector which stores the global score at each cell. - * By default, it is set very high to encourage exploration. pathScore is a - * vector which scores the length of the shortest path to that cell. - * - */ -void Planner::initializeSearchSpace( ) -{ - - int i; - int j; - - float iDistance; - float jDistance; - - for (int k = 0; k < (world.nCols * world.nRows); k++) - { - world.getStateFromIndex( k ); - - i = world.checkedMoveIndX; - j = world.checkedMoveIndY; - - iDistance = i - world.golLoc[ 0 ][ 0 ]; - jDistance = j - world.golLoc[ 0 ][ 1 ]; - - _searchMap.push_back( world.map.at< uchar >(Point(3*i, j)) ); - - _heuristic.push_back( pow ( sqrt( pow(iDistance,2) + pow(jDistance,2) ), - _epsilon ) ); - - _globalScore.push_back( 1e9 ); - - _pathScore.push_back( 1e9 ); - - } - path.resize( world.nRows * world.nCols ); - - _moves.resize( world.nRows * world.nCols ); - - _curLoc = world.getIndexFromState( world.robLoc[ 0 ][ 0 ], - world.robLoc[ 0 ][ 1 ] ); - - path[ _curLoc ].push_back( _curLoc ); - - _openSet.push_back( _curLoc ); - -} - -/** - * @brief getSearchNode - * - * Get next node to expand by returning the node with the current lowest global - * score from the openSet (nodes to be expanded). - * - * @return int - index of next node to search - */ -int Planner::getSearchNode( ) -{ - - int lowScore = 1e9; - - for (uint i = 0; i < _openSet.size(); i++) - { - if ( _globalScore[ _openSet[ i ] ] < lowScore ) - { - lowScore = _globalScore[ _openSet[ i ] ]; - - _curLoc = _openSet[ i ]; - } - } - - return _curLoc; - -} - -/** - * @brief getNeighbors - * - * Populate the moves vector with all legal moves at the current index. - * - * @param int - current search node index - */ -void Planner::getNeighbors( int _curLoc ) -{ - - _tempMoves = { _curLoc - 1, - _curLoc + 1, - _curLoc - world.nRows, - _curLoc + world.nCols, - _curLoc - 1 - world.nRows, - _curLoc - 1 + world.nRows, - _curLoc + 1 - world.nRows, - _curLoc + 1 + world.nRows }; - - _moves[ _curLoc ].clear(); - - for (uint i = 0; i < _tempMoves.size(); i++) - { - if ( world.checkMove( _tempMoves[ i ], world.robSize ) ) - { - _moves[ _curLoc ].push_back( _tempMoves[ i ] ); - - if ( std::find( _openSet.begin(), - _openSet.end(), - _tempMoves[ i ] ) - == _openSet.end() && - std::find( _closedSet.begin(), - _closedSet.end(), - _tempMoves[ i ] ) - == _closedSet.end() ) - { - _openSet.push_back( _tempMoves[ i ] ); - } - } - } -} - -/** - * @brief searchAStar - * - * Search the grid map for the optimal path. - * - * @param int - start location to search from - * @return int - number of waypoints in optimal path - */ -int Planner::searchAStar( int _curLoc ) -{ - - // start the clock to time performance. - float beginTime = clock(); - - // reset expandedNodes counter - _expandedNodes = 1; - - cout << endl << "Searching with A* . " << std::flush; - - while ( _endGame != true ) - { - - // expand the node in the openSet with lowest current score. - _curLoc = getSearchNode( ); - - // get x and y coordinates - world.getStateFromIndex( _curLoc ); - - // find all legal moves at the current node - getNeighbors( _curLoc ); - - // grade all legal moves to fully expand a node - for (uint j = 0; j < _moves[ _curLoc ].size(); j++) - { - - // set move to be graded - _newLoc = _moves[ _curLoc ][ j ]; - - // A* guarantees optimality along all expanded nodes, so there is no - // need to re-check. if move has been expanded, move along - if ( std::find( _closedSet.begin(), _closedSet.end(), _newLoc ) - != _closedSet.end() ) - { - continue; - } - - // if move is at goal state, end game and send back path - if ( world.checkGoal( _newLoc )) - { - // path @ newLoc will be the optimal path - path[ _newLoc ] = path[ _curLoc ]; - path[ _newLoc ].push_back( _newLoc ); - _curLoc = _newLoc; - _endGame = true; - goto doneSearching; - - } - else - { - - // do nothing unless the new path to the index is less than the - // current shortest path. This ensures that the global score is - // only modified if the searcher has found a shorter path. - if ( path[ _curLoc ].size() + 1 < _pathScore[ _newLoc ] ) - { - path[ _newLoc ] = path[ _curLoc ]; - - path[ _newLoc ].push_back( _newLoc ); - - _globalScore[ _newLoc ] = - _heuristic[ _newLoc ] - + path[ _newLoc ].size(); - - _pathScore[ _newLoc ] = path[ _newLoc ].size(); - } - } - } - - // once fully expanded, set the globalScore at the expanded node to a - // large number. This is done to discourage searching the same node. - _globalScore[ _curLoc ] = 1e9; - - // erase the current node from the openSet (nodes to be expanded). - _openSet.erase( - std::remove( _openSet.begin(), _openSet.end(), _curLoc ), - _openSet.end() ); - - // add the current node to the closedSet (nodes that have been expanded) - _closedSet.push_back( _curLoc ); - - // increase expanded node counter - ++_expandedNodes; - - // print a "." for every 1000 nodes expanded as a progress meter - if ( _expandedNodes % 1000 == 0 ) - { - cout << ". " << std::flush; - } - } - - // what to do at endGame - doneSearching: - - float endTime = float( clock() - beginTime ) / float( CLOCKS_PER_SEC ); - - cout << endl << "Path Optimized, " << _expandedNodes << " nodes expanded."; - cout << endl << "Total Optimization time: " << endTime << " seconds"<< endl; - cout << endl << "Press the return key to execute optimal path." << endl; - - cin.get(); - - cout << "Optimal path is " << path[ _curLoc ].size() << " steps long."; - cout << endl; - - return path[ _curLoc ].size(); - -} - -/** - * @brief plotOptimalPath - * - * Defunct; Iterate through path and plot waypoints. - * - */ -void Planner::plotOptimalPath( ) -{ - cout << "Press the return key to execute optimal path." << endl; - - cin.get(); - - cout << "Optimal path is " << path[ _curLoc ].size() << " steps long."; - cout << endl; - - for( uint k = 0; k < path[ _curLoc ].size(); k++) - { - world.getStateFromIndex( path[ _curLoc ][ k ] ); - - world.moveRobot( world.checkedMoveIndX, world.checkedMoveIndY ); - } - - cout << "GOAL!!" << endl; -} - -/** - * @brief getGoalX - * - * return x-coordinate for the goal location - * - * @return int - x-coordinate for goal location - */ -int Planner::getGoalX( ) -{ - return world.golLoc[ 0 ][ 0 ]; -} - -/** - * @brief getGoalY - * - * return y-coordinate for the goal location - * - * @return int - y-coordinate for goal location - */ -int Planner::getGoalY( ) -{ - return world.golLoc[ 0 ][ 1 ]; -} - -/** - * @brief getNextWaypoint - * - * return next waypoint from input location - * - * @param int - waypoint ID that robot is at - * @return int - index at waypoint ID - */ -int Planner::getNextWaypoint( int index ) -{ - return path[ _curLoc ][ index ]; -} - -/** - * @brief getNextWaypoint - * - * return next waypoint from input location - * - * @return int - index at waypoint ID - */ -int Planner::getPathSize( ) -{ - return path[ _curLoc ].size(); -} - -Planner::~Planner() { - -} diff --git a/PolysyncLidarTranslator/README.md b/PolysyncLidarTranslator/README.md deleted file mode 100644 index c6e0856..0000000 --- a/PolysyncLidarTranslator/README.md +++ /dev/null @@ -1,103 +0,0 @@ -## LiDAR Translator - -This example is a generalized LiDAR message translator for messages coming from PolySync into ROS via the PolySync ROS bridge. It is generalized to work with any LiDAR driver or application running in PolySync. - -Each PointCloud2 message will contain the source GUID of the driver sending the `ps_lidar_points_msg` in its frame_id field. Thus, you can differentiate the incoming data as necessary. Similarly, the PolySync timestamp is copied over to the native PointCloud2 messages. - -The transform for each incoming message of a particular GUID can be manually modified to match what is in the PolySync SDF. This allows simple sensor translation so that the data is correctly kept relative to the vehicles center frame, as in PolySync. - -It would be easy to adapt this example to publish data in the other direction. This example could be adapted to republish `ps_radar_targets_msg` to PointCloud2, allowing you to use all RADAR drivers in PolySync with ROS. This example is intended to be very easy to use while still being powerful in its potential applications. - -### Building and running the example - -To properly build this example with the generated PolySync messages in ROS, you will first need to set up your catkin workspace with the ros_bridge. - -If you do not have a catkin workspace already, follow these steps to set one up. - -http://wiki.ros.org/catkin/Tutorials/create_a_workspace - -If you do have a workspace, feel free to continue with the steps below. First source your ROS install, and then create a package in the src directory of your catkin workspace, as shown below. - -```bash -$ cd ~/catkin_ws/src -$ source /opt/ros/indigo/setup.bash -$ catkin_create_pkg polysync_lidar_translator std_msgs roscpp tf -``` - -Copy "polysync_lidar_translator_node.cpp" to the src directory of the polysync_lidar_translator package you created. - -```bash -$ cp PolySync-Core-CPP-Examples/PolysyncLidarTranslator/polysync_lidar_translator_node.cpp ~/catkin_ws/src/polysync_lidar_translator/src/ -``` - -Make sure that in the "Build" section of the CMakeLists file for your PolysyncLidarTranslator project are uncommented. All other lines in the "Build" section should be commented. - -```bash -## include_directories(include) -include_directories( - ${catkin_INCLUDE_DIRS} -) - -## Declare a C++ executable -add_executable(polysync_lidar_translator_node src/polysync_lidar_translator_node.cpp) - -## Add cmake target dependencies of the executable -## same as for the library above -add_dependencies(polysync_lidar_translator_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) - -## Specify libraries to link a library or executable target against -target_link_libraries(polysync_lidar_translator_node - ${catkin_LIBRARIES} - ) -``` - -Generate the ros_bridge files in the src folder of your catkin workspace, and copy the ros_bridge project into the root directory of your catkin workspace, as shown below. - -```bash -$ cd ~/catkin_ws/src -$ pdm-gen -r -c /usr/local/polysync/modules/sensor/sensor.idl /usr/local/polysync/modules/navigation/navigation.idl /usr/local/polysync/modules/control/control.idl /usr/local/polysync/modules/dtc/dtc.idl -$ mv pdm/ros_bridge ../ -$ rm -rf pdm -``` - -Source the ros_bridge, and then run catkin_make in the root directory of your catkin workspace. - -```bash -$ cd ~/catkin_ws -$ source ros_bridge/setup.bash -$ catkin_make -``` - -Run ROS bridge node as shown below, remembering to source ros_bridge/setup.bash if using a different terminal. - -```bash -$ cd ~/catkin_ws/ros_bridge/share/polysync_ros_bridge -$ ./BridgeNode -t ps_lidar_points_msg -``` - -Start up PolySync data generator in another terminal. - -```bash -$ git clone git@github.com:PolySync/PolySync-Core-CPP-Examples.git -$ cd PolySync-Core-CPP-Examples/DataGenerator -$ sudo apt-get install libglib2.0-dev # this is required for this example to build, documented in the examples README.md file -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-data-generator-cpp -``` - -Run the translator project you just built. The executable should be in the devel folder of your catkin workspace. - -```bash -$ cd ~/catkin_ws/devel/lib/polysync_lidar_translator -$ ./polysync_lidar_translator_node -``` - -Open up rviz. - -```bash -$ rosrun rviz rviz -``` - -In "Global Options" for the fixed frame select "world," then hit "add" and add a new "PointCloud2" visualization. For the topic of this new visualization select "/polysync/lidar_points." You can change the style to "Points" to have a little more realistic looking LiDAR point cloud. diff --git a/PolysyncLidarTranslator/polysync_lidar_translator_node.cpp b/PolysyncLidarTranslator/polysync_lidar_translator_node.cpp deleted file mode 100644 index f736f1e..0000000 --- a/PolysyncLidarTranslator/polysync_lidar_translator_node.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include -#include -#include -#include -#include - - -using namespace sensor_msgs; - - - - -// -void addFieldToPointCloud( - PointCloud2 * cloud, - std::string name, - int offset, - int dataType, - int count ) -{ - PointField field; - - field.name = name; - - field.offset = offset; - - field.datatype = dataType; - - field.count = count; - - cloud->fields.push_back( field ); -} - - -// -void publishLidarTransform( - std::string frame_id, - double x, - double y, - double z, - double roll, - double pitch, - double yaw ) -{ - static tf::TransformBroadcaster br; - - tf::Transform transform; - - transform.setOrigin( tf::Vector3( x, y, z ) ); - - tf::Quaternion q; - - q.setRPY( roll, pitch, yaw ); - - transform.setRotation(q); - - br.sendTransform( tf::StampedTransform( - transform, - ros::Time::now(), - "world", - frame_id ) ); -} - - -// CallBack for PolySync Lidar Points -void lidarCallback( - const polysync_ros_bridge::ps_lidar_points_msg::ConstPtr& msg, - ros::Publisher * lidar_pub ) -{ - PointCloud2 cloud; - - ros::Time timer; - - // Get the source GUID as a string - std::ostringstream src_guid_ss; - src_guid_ss << msg->ps_header.src_guid; - std::string src_guid = src_guid_ss.str(); - - // get PS timestamp in nanoseconds - unsigned long long ps_nanoseconds = msg->ps_header.timestamp*1000; - - //Consistant timestamp for all lidar points in this single message - uint headerSize = sizeof( msg->points[0].header ); - uint dataPointSize = sizeof( msg->points[0] ) - headerSize; - uint pointSize = sizeof(msg->points[0].position) / 3; - - uint dataPointsSize = msg->points.size() * ( headerSize + dataPointSize ); - - cloud.header.frame_id = src_guid; - cloud.header.stamp = timer.fromNSec( ps_nanoseconds ); - - cloud.is_bigendian = false; - cloud.is_dense = true; - - cloud.height = 1; - - // number of points in message - cloud.width = msg->points.size(); - - cloud.point_step = headerSize + dataPointSize; - cloud.row_step = dataPointsSize; - - - addFieldToPointCloud( - &cloud, - "x", - headerSize, - PointField::FLOAT32, - msg->points.size() ); - - addFieldToPointCloud( - &cloud, - "y", - headerSize + pointSize*1, - PointField::FLOAT32, - msg->points.size() ); - - addFieldToPointCloud( - &cloud, - "z", - headerSize + pointSize*2, - PointField::FLOAT32, - msg->points.size() ); - - // intensity - addFieldToPointCloud( - &cloud, - "i", - headerSize + pointSize*3, - PointField::UINT8, - msg->points.size() ); - - cloud.data.resize( dataPointsSize ); - - std::memcpy( - cloud.data.data(), - msg->points.data(), - dataPointsSize ); - - //Publish array of markers as a single message - lidar_pub->publish( cloud ); - - // TODO : get transform values from PolySync SDF, for a specific GUID, and - // load them in here - publishLidarTransform( src_guid, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ); -} - - - - -// -int main( int argc, char** argv ) -{ - ros::init( argc, argv, "polysync_lidar_translator" ); - - ros::NodeHandle rosnode; - - ros::Publisher lidar_pub; - - ros::Subscriber lidar_sub; - - lidar_pub = - rosnode.advertise < sensor_msgs::PointCloud2 > - ( "polysync/lidar_points", - 1 ); - - lidar_sub = - rosnode.subscribe < polysync_ros_bridge::ps_lidar_points_msg > - ( "polysync/ps_lidar_points_msg", - 1000, - boost::bind( lidarCallback, _1, &lidar_pub ) ); - - ros::spin(); - - return 0; - -} diff --git a/PublishSubscribe/CMakeLists.txt b/PublishSubscribe/CMakeLists.txt deleted file mode 100644 index dbd12a4..0000000 --- a/PublishSubscribe/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-publisher-subscriber-cpp ) - - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - PublishSubscribe.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/PublishSubscribe/Publish/CMakeLists.txt b/PublishSubscribe/Publish/CMakeLists.txt deleted file mode 100644 index 6ef78fa..0000000 --- a/PublishSubscribe/Publish/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-publisher-cpp ) - - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - Publish.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/PublishSubscribe/Publish/Publish.cpp b/PublishSubscribe/Publish/Publish.cpp deleted file mode 100644 index e8f73f5..0000000 --- a/PublishSubscribe/Publish/Publish.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example Publish.cpp - * - * Publish/Subscribe Example. - * - * Shows how to use publish/subscribe communication model, and the Messaging API - * routines. This half of the example code populates and publishes a message - * to the PolySync bus. - * - * The second half of the example - Subscribe.cpp - runs as a seperate node, - * and subscribes to the messages to access the data buffer. - * - * The example uses the standard PolySync node template and state machine. - * Send the SIGINT (control-C on the keyboard) signal to the node/process to do - * a graceful shutdown. - * - */ - -#include -#include -#include - -using namespace std; - -/** - * Node flags to be OR'd with node flags during the build. - * - */ -#ifndef NODE_FLAGS_VALUE -#define NODE_FLAGS_VALUE (0) -#endif - -/** - * @brief PublisherSubscriberNode class - * - * - */ -class PublisherSubscriberNode : public polysync::Node -{ - -private: - const string node_name = "polysync-publish-cpp"; - const string platform_motion_msg_name = "ps_platform_motion_msg"; - - ps_msg_type _messageType; - -public: - - PublisherSubscriberNode() - { - setNodeType( PSYNC_NODE_TYPE_API_USER ); - setDomainID( PSYNC_DEFAULT_DOMAIN ); - setSDFID( PSYNC_SDF_ID_INVALID ); - setFlags( NODE_FLAGS_VALUE | PSYNC_INIT_FLAG_STDOUT_LOGGING ); - setNodeName( node_name ); - } - - ~PublisherSubscriberNode() - { - - } - - void initStateEvent() override - { - _messageType = getMessageTypeByName( platform_motion_msg_name ); - } - - void releaseStateEvent() override - { - // do nothing, sleep for 10 milliseconds - } - - void errorStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void fatalStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void warnStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - /** - * Override the base class functionality to send messages when the node - * reaches the "ok" state. This is the state where the node is in its - * normal operating mode. - */ - void okStateEvent() override - { - // Create a message - polysync::datamodel::PlatformMotionMessage message( *this ); - - // Set message data - message.setHeaderTimestamp( polysync::getTimestamp() ); - message.setLatitude( 45.515289 ); - message.setLongitude( -122.654355 ); - - // Publish to the PolySync bus - message.publish(); - - // The ok state is called periodically by the system, sleep to reduce - // the number of messages sent - polysync::sleepMicro( 1000000 ); - } -}; - - -/** - * Entry point for this node - * The "connectToPolySync" is a blocking call, users must use Ctrl-C to quit - * the execution loop. - */ -int main() -{ - // Create an instance of the PublisherSubscriberNode and connect it to - // PolySync - PublisherSubscriberNode publisherSubscriberNode; - - // When the node has been created, it will cause an initStateEvent to be - // sent and then proceed into the okState. connectToPolySync does not - // return, use Ctrl-C to exit - publisherSubscriberNode.connectPolySync(); - - return 0; -} diff --git a/PublishSubscribe/PublishSubscribe.cpp b/PublishSubscribe/PublishSubscribe.cpp deleted file mode 100644 index 0c1e9a1..0000000 --- a/PublishSubscribe/PublishSubscribe.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example PublishSubscribe.cpp - * - * Publish/Subscribe Example. - * - * Shows how to use publish/subscribe routines. - * The example code registers a subscriber to PolySync diagnostic messages and - * publishes event messages. - * - * The example uses the standard PolySync node template and state machine. - * Send the SIGINT (control-C on the keyboard) signal to the node/process to do - * a graceful shutdown. - * - */ - -#include -#include -#include - -using namespace std; - -/** - * @brief Node flags to be OR'd with driver/interface flags. - * - * Provided by the compiler so PolySync can add build-specifics as needed. - * - */ -#ifndef NODE_FLAGS_VALUE -#define NODE_FLAGS_VALUE (0) -#endif - -/** - * @brief PublisherSubscriberNode class - * - * The PublisherSubscriberNode class exists to override the functions defined in the - * base class. The functions exist in the base class but are stubbed out - * and must be overloaded in order for them to do something. In this instance - * we are overriding the main functions for sending and receiving messages as - * well as responding to error and warning type events. - * - */ -class PublisherSubscriberNode : public polysync::Node -{ -private: - const string node_name = "polysync-publish-subscribe-cpp"; - const string diagnostic_trace_msg_name = "ps_diagnostic_trace_msg"; - const string event_msg_name = "ps_event_msg"; - - ps_msg_type _messageType; - -public: - - PublisherSubscriberNode() - { - setNodeType( PSYNC_NODE_TYPE_API_USER ); - setDomainID( PSYNC_DEFAULT_DOMAIN ); - setSDFID( PSYNC_SDF_ID_INVALID ); - setFlags( NODE_FLAGS_VALUE | PSYNC_INIT_FLAG_STDOUT_LOGGING ); - setNodeName( node_name ); - } - - ~PublisherSubscriberNode() - { - - } - - void initStateEvent() override - { - _messageType = getMessageTypeByName( diagnostic_trace_msg_name ); - - // Register as a listener for diagnostic messages that any nodes may - // send. - registerListener( _messageType ); - } - - void releaseStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void errorStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void fatalStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void warnStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - /** - * @brief okStateEvent - * - * Override the base class functionality to send messages when the node - * reaches the "ok" state. This is the state where the node is in its - * normal operating mode. - * - * @param void - * @return void - */ - void okStateEvent() override - { - // Create a message - polysync::datamodel::EventMessage message( *this ); - - // Set message data - message.setHeaderTimestamp( polysync::getTimestamp() ); - message.setId(0); - - // Publish to the PolySync bus - message.publish(); - - // The ok state is called periodically by the system so sleep to reduce - // the number of messages sent. - polysync::sleepMicro( 1000000 ); - } - - /** - * @brief messageEvent - * - * Extract the information from the provided message - * - * @param std::shared_ptr< Message > - variable containing the message - * @return void - */ - void messageEvent( std::shared_ptr< polysync::Message > message ) override - { - using namespace polysync::datamodel; - if( auto diagnosticMsg = - getSubclass< DiagnosticTraceMessage >( message ) ) - { - diagnosticMsg->print(); - } - } - -}; - - -/** - * @brief main - * - * Entry point for this tutorial application - * The "connectToPolySync" is a blocking call, users must use Ctrl-C to exit - * this function. - * - * @return int - exit code - */ -int main() -{ - // Create an instance of the PublisherSubscriberNode and connect it to - // PolySync. - PublisherSubscriberNode publisherSubscriberNode; - - // When the node has been created, it will cause an initStateEvent to be - // sent and then proceed into the okState. connectToPolySync does not - // return, use Ctrl-C to exit. - publisherSubscriberNode.connectPolySync(); - - return 0; -} diff --git a/PublishSubscribe/README.md b/PublishSubscribe/README.md deleted file mode 100644 index 3bb8346..0000000 --- a/PublishSubscribe/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### PublishSubscribe - -This example illustrates the simple publish and subscribe functionality found in PolySync. -It publishes an empty `ps_event_msg` to demonstrate how the publish functionality works in PolySync. -It subscribes to all diagnostic messages on the PolySync bus, and then prints the info each diagnostic message contains as they are received in real time. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd PublishSubscribe -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-publisher-subscriber-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/PublishSubscribe/Subscribe/CMakeLists.txt b/PublishSubscribe/Subscribe/CMakeLists.txt deleted file mode 100644 index 0627e32..0000000 --- a/PublishSubscribe/Subscribe/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-subscriber-cpp ) - - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - Subscribe.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/PublishSubscribe/Subscribe/Subscribe.cpp b/PublishSubscribe/Subscribe/Subscribe.cpp deleted file mode 100644 index 7e829af..0000000 --- a/PublishSubscribe/Subscribe/Subscribe.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example Subscribe.cpp - * - * Publish/Subscribe Example. - * - * Shows how to use publish/subscribe communication model, and the Messaging API - * routines. This is the second half of the publish/subscribe example. This node - * subscribes to the message published from the Publish.cpp node. - * - * The example uses the standard PolySync node template and state machine. - * Send the SIGINT (control-C on the keyboard) signal to the node/process to do - * a graceful shutdown. - * - */ - -#include -#include -#include - -using namespace std; - -/** - * @brief Node flags to be OR'd with driver/interface flags. - */ -#ifndef NODE_FLAGS_VALUE -#define NODE_FLAGS_VALUE (0) -#endif - -/** - * The PublisherSubscriberNode class exists to override the functions defined in the - * base class. The functions exist in the base class but are stubbed out - * and must be overloaded in order for them to do something. In this instance - * we are overriding the main functions for sending and receiving messages as - * well as responding to error and warning type events. - * - */ -class PublisherSubscriberNode : public polysync::Node -{ -private: - const string node_name = "polysync-subscribe-cpp"; - const string platform_motion_msg_name = "ps_platform_motion_msg"; - - ps_msg_type _messageType; - -public: - - PublisherSubscriberNode() - { - setNodeType( PSYNC_NODE_TYPE_API_USER ); - setDomainID( PSYNC_DEFAULT_DOMAIN ); - setSDFID( PSYNC_SDF_ID_INVALID ); - setFlags( NODE_FLAGS_VALUE | PSYNC_INIT_FLAG_STDOUT_LOGGING ); - setNodeName( node_name ); - } - - ~PublisherSubscriberNode() - { - - } - - void initStateEvent() override - { - _messageType = getMessageTypeByName( platform_motion_msg_name ); - - // Register as a listener for the platform motion message - registerListener( _messageType ); - } - - void releaseStateEvent() override - { - // do nothing, sleep for 10 milliseconds - } - - void errorStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void fatalStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - void warnStateEvent() override - { - // do nothing, sleep for 10 milliseconds - polysync::sleepMicro( 10000 ); - } - - /** - * Override the base class functionality to send messages when the node - * reaches the "ok" state. This is the state where the node is in its - * normal operating mode. - */ - void okStateEvent() override - { - // The ok state is called periodically by the system - polysync::sleepMicro( 10000 ); - } - - /** - * Extract the information from the provided message - * - * @param std::shared_ptr< Message > - variable containing the message - */ - void messageEvent( std::shared_ptr< polysync::Message > message ) override - { - using namespace polysync::datamodel; - if( std::shared_ptr < polysync::datamodel::PlatformMotionMessage > platformMotionMsg = - getSubclass< PlatformMotionMessage >( message ) ) - { - //platformMotionMsg->print(); - - // or... - - std::cout << "Latitude: " << platformMotionMsg->getLatitude() << std::endl; - std::cout << "Longitude: " << platformMotionMsg->getLongitude() << std::endl; - - } - } - -}; - - -/** - * @brief main - * - * Entry point for this tutorial application - * The "connectToPolySync" is a blocking call, users must use Ctrl-C to exit - * this function. - * - * @return int - exit code - */ -int main() -{ - // Create an instance of the PublisherSubscriberNode and connect it to - // PolySync. - PublisherSubscriberNode publisherSubscriberNode; - - // When the node has been created, it will cause an initStateEvent to be - // sent and then proceed into the okState. connectToPolySync does not - // return, use Ctrl-C to exit. - publisherSubscriberNode.connectPolySync(); - - return 0; -} diff --git a/QtImageViewer/CMakeLists.txt b/QtImageViewer/CMakeLists.txt deleted file mode 100644 index e0de71d..0000000 --- a/QtImageViewer/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-qt-image-viewer-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -set( CMAKE_INCLUDE_CURRENT_DIR ON ) -set( CMAKE_AUTOMOC ON ) - -find_package( Qt5Widgets ) - -add_executable( ${PROJECT_NAME} - main.cpp - ImageDataNode.cpp - ImageDataProcessor.cpp - ImageDataView.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} - Qt5::Widgets -) diff --git a/QtImageViewer/ImageDataNode.cpp b/QtImageViewer/ImageDataNode.cpp deleted file mode 100644 index b111b43..0000000 --- a/QtImageViewer/ImageDataNode.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include - -#include "ImageDataNode.hpp" - - -ImageDataNode::ImageDataNode() -{ - // Inform Qt event loop about std:: type passed from signal to slot - qRegisterMetaType< std::vector< uchar > >( "std::vector< uchar >&" ); - - moveToThread( &thread ); - - thread.start(); -} - - -ImageDataNode::~ImageDataNode() -{ - disconnectPolySync(); - - thread.quit(); - - thread.wait(); -} - - -void ImageDataNode::slotRun() -{ - connectPolySync(); -} - - -void ImageDataNode::initStateEvent() -{ - registerListener( getMessageTypeByName( "ps_image_data_msg" ) ); -} - - -void ImageDataNode::messageEvent( std::shared_ptr< polysync::Message > message ) -{ - using namespace polysync::datamodel; - - if( auto imageDataMsg = getSubclass< ImageDataMessage >( message ) ) - { - if( imageDataMsg->getPixelFormat() == PIXEL_FORMAT_MJPEG ) - { - signalFrameBuffer( imageDataMsg->getDataBuffer() ); - } - else - { - std::cout << "Warning: unsupported pixel format type; " - "this image data is not viewable\n"; - } - - } -} diff --git a/QtImageViewer/ImageDataNode.hpp b/QtImageViewer/ImageDataNode.hpp deleted file mode 100644 index 1bf06a9..0000000 --- a/QtImageViewer/ImageDataNode.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef IMAGE_DATA_NODE_H -#define IMAGE_DATA_NODE_H - - -#include -#include - -#include - - -/** - * @brief The ImageDataNode class - * This class is the interface to PolySync. It is responsible for connecting - * to PolySync and registering to listen for image data. When a PolySync Video - * Device publishes image data, this node receives it and passes the frame - * buffer to the ImageDataProcessor. - * - * @note This object is contained in a separate QThread to allow both the - * polysync::Node event loop and the QApplication event loop to run - * asychronously. - */ -class ImageDataNode : public QObject, public polysync::Node -{ - // Qt Macro allowing for signals/slots - Q_OBJECT - -public: - - ImageDataNode(); - - ~ImageDataNode(); - - -public slots: - - /** - * Calls polysync::Node::connectPolySync() which is a blocking event loop. - */ - void slotRun(); - - -signals: - - /** - * Pass image frame to ImageDataProcessor - * @param frameBuffer This represents a single image data frame - */ - void signalFrameBuffer( const std::vector< uchar > & frameBuffer ); - - -private: - - void initStateEvent() override; - - void messageEvent( std::shared_ptr< polysync::Message > message ) override; - - QThread thread; - -}; - - -#endif diff --git a/QtImageViewer/ImageDataProcessor.cpp b/QtImageViewer/ImageDataProcessor.cpp deleted file mode 100644 index e72073f..0000000 --- a/QtImageViewer/ImageDataProcessor.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "ImageDataProcessor.hpp" - -#include - - -ImageDataProcessor::ImageDataProcessor() - : - decoder( { PIXEL_FORMAT_MJPEG, IMAGE_WIDTH, IMAGE_HEIGHT, FRAME_RATE }, - { PIXEL_FORMAT_RGB24, IMAGE_WIDTH, IMAGE_HEIGHT, FRAME_RATE } ) -{} - - -void ImageDataProcessor::slotFrameBuffer( - const std::vector< uchar > & frameBuffer ) -{ - auto decodedBuffer = decodeBuffer( frameBuffer ); - - if( decodedBuffer.size() > 0 ) - { - auto image = buildQImageFromFrameBuffer( decodedBuffer ); - - if( not image.isNull() ) - { - emit signalPixmap( image ); - } - } -} - - -std::vector< uchar > ImageDataProcessor::decodeBuffer( - const std::vector & buffer ) -{ - decoder.decode( buffer ); - - return decoder.getCopyOfDecodedBuffer(); -} - - -QImage ImageDataProcessor::buildQImageFromFrameBuffer( - const std::vector< uchar > & buffer ) -{ - return QImage{ - buffer.data(), IMAGE_WIDTH, IMAGE_HEIGHT, QImage::Format_RGB888 }; -} diff --git a/QtImageViewer/ImageDataProcessor.hpp b/QtImageViewer/ImageDataProcessor.hpp deleted file mode 100644 index 0a1bf55..0000000 --- a/QtImageViewer/ImageDataProcessor.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef IMAGE_DATA_PROCESSOR_H -#define IMAGE_DATA_PROCESSOR_H - - -#include -#include -#include -#include - -#include -#include - -/** - * @brief The ImageDataProcessor class - * This class is responsible for interaction with PolySync and the incoming image data - * messages. - * This class connects to the PolySync bus, and subscribes to the ImageDataMessage - * (ps_image_data_msg) - * For each image received, a signal is emitted to the ImageDataView to render. - */ -class ImageDataProcessor : public QObject, public polysync::Node -{ - // Qt Macro allowing for signals/slots - Q_OBJECT - -public: - - ImageDataProcessor(); - - -public slots: - - void slotFrameBuffer( const std::vector< uchar > & frameBuffer ); - - -signals: - - /** - * Qt Signal emitted when new data is ready for rendering. This triggers - * @ref VideoViewer::slotUpdatePixmap, passing the new QPixmap to draw. - */ - void signalPixmap( const QImage & ); - - -private: - - QImage buildQImageFromFrameBuffer( const std::vector< uchar > & buffer ); - - std::vector< uchar > decodeBuffer( - const std::vector< uchar > & buffer ); - - polysync::VideoDecoder decoder; - - static constexpr auto IMAGE_WIDTH = 320; - - static constexpr auto IMAGE_HEIGHT = 240; - - static constexpr auto FRAME_RATE = 30; -}; - - -#endif // IMAGE_DATA_PROCESSOR_H diff --git a/QtImageViewer/ImageDataView.cpp b/QtImageViewer/ImageDataView.cpp deleted file mode 100644 index 03a1d3d..0000000 --- a/QtImageViewer/ImageDataView.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "ImageDataView.hpp" - -#include -#include -#include - - -ImageDataView::ImageDataView() - : - _layout( new QHBoxLayout( this ) ), - _label( new QLabel( this ) ) -{ - // Set viewing window to an appropriate size. - resize( 320, 240 ); - - // Add layout element to this widget. - setLayout( _layout ); - - // Add label to this widget. The label contains the QPixmap that we update. - _layout->addWidget( _label ); - - // Make this widget/window visible on screen. - show(); -} - -void ImageDataView::slotRenderImage( const QImage & image ) -{ - auto pixmap = QPixmap::fromImage( image ); - - if( not pixmap.isNull() ) - { - // Update the view - _label->setPixmap( pixmap ); - } -} diff --git a/QtImageViewer/ImageDataView.hpp b/QtImageViewer/ImageDataView.hpp deleted file mode 100644 index faa23d3..0000000 --- a/QtImageViewer/ImageDataView.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef IMAGE_DATA_VIEW_H -#define IMAGE_DATA_VIEW_H - - -#include - -class QHBoxLayout; -class QLabel; - -/** - * @brief The ImageDataView class - * This class contains the Qt GUI view. It's job is to receive and render image - * data. - */ -class ImageDataView : public QWidget -{ - // Qt Macro enabling Qt signals and slots - Q_OBJECT - -public: - - /** - * Allocates resources for @ref _label and @ref _layout, then adds them - * to this widget. Calls QWidget::show() to make the widget appear on - * screen. - */ - ImageDataView(); - - -public slots: - - /** - * Triggered from VideoProcessor when new data is available to render. - * @param [in] pixmap Updated pixmap to render on @ref _label. - */ - void slotRenderImage( const QImage & pixmap ); - - -private: - - QHBoxLayout * _layout; - - QLabel * _label; - -}; - - -#endif // IMAGE_DATA_VIEW_H diff --git a/QtImageViewer/README.md b/QtImageViewer/README.md deleted file mode 100644 index e2bc446..0000000 --- a/QtImageViewer/README.md +++ /dev/null @@ -1,65 +0,0 @@ -### QtImageViewer - -This example creates a GUI application using Qt to visualize PolySync image data. -It contains a threaded VideoProcessor (polysync::Node) that receives image data from the PolySync -bus and packages it for rendering in a QWidget. - -### Hardware requirements - -Sensors: Video Device - -* Note: Sensor must be configured to publish MJPEG. - -### Install Dependencies - -A Qt install and mesa-common-dev Debian package are required to run this example. - -1. [Download Qt installer here](http://www.qt.io/download/) - -2. Navigate to Downloads directory - - `cd ~/Downloads` - -3. Make the installer executable **NOTE**: make sure the name of the *.run file matches - - `chmod +x qt-unified-online-installer.run` - -4. Run the installer, this can take up to 30 minutes **NOTE**: Only the desktop libraries are required, you can uncheck other elements (such as QtCreator) in the installer to speed up the process. - - `./qt-unified-online-installer.run` - -5. Install OpenGL - - `sudo apt install mesa-common-dev` - -6. Follow the build instructions. - -7. Run the node. - - -### Building and running the node - -#### Build - -```bash -# Tell cmake where to find Qt, note that the path listed below may need to be modified if Qt is not in the default location or is a different version -$ export CMAKE_PREFIX_PATH=~/Qt5.8.0/5.8/gcc_64 -$ cd QtImageViewer -$ mkdir build && cd build -$ cmake .. -$ make -``` - -#### Run -```bash -# Note that the path listed below may need to be modified if Qt is not in the default location or is a different version -$ export QT_QPA_PLATFORM_PLUGIN_PATH=~/Qt5.8.0/5.8/gcc_64/plugins/platforms -$ ./polysync-qt-image-viewer-cpp -``` - - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). - - - - diff --git a/QtImageViewer/main.cpp b/QtImageViewer/main.cpp deleted file mode 100644 index 0907c3a..0000000 --- a/QtImageViewer/main.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -#include "ImageDataNode.hpp" -#include "ImageDataProcessor.hpp" -#include "ImageDataView.hpp" - - -int main( int argc, char *argv[] ) -{ - // Object required to execute Qt GUI functionality - QApplication app( argc, argv ); - - ImageDataNode imageDataNode; - - ImageDataProcessor imageDataProcessor; - - ImageDataView imageDataView; - - // Qt Signal/Slot connections - // Enables async message passing from node to processor - QObject::connect( &imageDataNode, &ImageDataNode::signalFrameBuffer, - &imageDataProcessor, &ImageDataProcessor::slotFrameBuffer ); - - // Enable async message passing between processor and view - QObject::connect( &imageDataProcessor, &ImageDataProcessor::signalPixmap, - &imageDataView, &ImageDataView::slotRenderImage ); - - // Start the PolySync event loop in 50 milliseconds. Allow the next - // statement to spawn the Qt event loop. - QTimer::singleShot( 50/*ms*/, &imageDataNode, SLOT( slotRun() ) ); - - // Begin the blocking Qt event loop - app.exec(); -} diff --git a/QtImageViewer/res/qt.conf b/QtImageViewer/res/qt.conf deleted file mode 100644 index e69de29..0000000 diff --git a/README.md b/README.md deleted file mode 100644 index 6c85f53..0000000 --- a/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# PolySync Examples in C++ - -Here you can find examples that demonstrate how to use PolySync's APIs. - -## Core APIs - -- [HelloWorld](https://github.com/PolySync-Core-CPP-Examples/tree/master/HelloWorld) - Create a node and process node-level events. -- [HelloWorldPublisher](https://github.com/PolySync-Core-CPP-Examples/tree/master/HelloWorldPublisher) - Publish a message from a node to the PolySync bus. -- [HelloWorldSubscriber](https://github.com/PolySync-Core-CPP-Examples/tree/master/HelloWorldSubscriber) - Subscribe a node to messages on the PolySync bus. -- [Publish & Subscribe](https://github.com/PolySync-Core-CPP-Examples/tree/master/PublishSubscribe) - Use publish/subscribe routines. -- [Coordinate Transformation (single)](https://github.com/PolySync-Core-CPP-Examples/tree/master/SingleTransform) - Use the Transform API to create transform coordinate frames. -- [Coordinate Transformation (stack)](https://github.com/PolySync-Core-CPP-Examples/tree/master/TransformStack) - Use the Transform API to transform coordinate frames using a stack. -- [Sample Application](https://github.com/PolySync-Core-CPP-Examples/tree/master/SampleApplication) - Create an application node. - -## Message APIs - -- [Shared Memory Image Data Viewer](https://github.com/PolySync-Core-CPP-Examples/tree/master/SharedMemoryImageDataViewer) - View image data received over the PolySync shared memory queue. -- [Paramater Get/Set](https://github.com/PolySync-Core-CPP-Examples/tree/master/ParameterGetSet) - Get/set parameters from the PolySync bus. - -## Device APIs - -- [Socket Reader](https://github.com/PolySync-Core-CPP-Examples/tree/master/SocketReader) - Read data from a network device. -- [Socket Writer](https://github.com/PolySync-Core-CPP-Examples/tree/master/SocketWriter) - Write data to a network device. -- [Serial Reader](https://github.com/PolySync-Core-CPP-Examples/tree/master/SerialReader) - Read data from a serial device. -- [Serial Writer](https://github.com/PolySync-Core-CPP-Examples/tree/master/SerialWriter) - Write data to a serial device. -- [CAN Reader](https://github.com/PolySync-Core-CPP-Examples/tree/master/CANReader) - Read data from a CAN device. -- [CAN Writer](https://github.com/PolySync-Core-CPP-Examples/tree/master/CANWriter) - Write data to a CAN device. -- [Video Device Viewer](https://github.com/PolySync-Core-CPP-Examples/tree/master/VideoDeviceViewer) - Interact with a Video Device. -- [Video Device With Encode/Decode](https://github.com/PolySync-Core-CPP-Examples/tree/master/VideoEncodeDecode) - Communicate with a video device, encode, and decode video data. - -## Utilities and Cool Stuff - -- [Data Generator](https://github.com/PolySync-Core-CPP-Examples/tree/master/DataGenerator) - Publish various PolySync message types with pseudo-random data. -- [Record](https://github.com/PolySync-Core-CPP-Examples/tree/master/Record) - Record PolySync bus data. -- [Replay](https://github.com/PolySync-Core-CPP-Examples/tree/master/Replay) - Replay PolySync bus data. - - -## PolySync Resources -- [Complete List of Examples](https://help.polysync.io/articles/) -- [Help Center](https://help.polysync.io) - - diff --git a/Record/CMakeLists.txt b/Record/CMakeLists.txt deleted file mode 100644 index d2a8fa8..0000000 --- a/Record/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-record-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - Record.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/Record/README.md b/Record/README.md deleted file mode 100644 index dd61d10..0000000 --- a/Record/README.md +++ /dev/null @@ -1,31 +0,0 @@ -### Record - -Record is more of a tool than an example. It exposes much of the functionality of the RecordSession API as a command line tool. -This is an interactive application, which expects you to enter the record session ID and allows you to stop the recording. -As an example, this code illustrates how to properly access the RecordSession APIs functionality. - -### Hardware requirements - -A sensor or video device. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd Record -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-record-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/Record/Record.cpp b/Record/Record.cpp deleted file mode 100644 index f891717..0000000 --- a/Record/Record.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example Record.cpp - * - * Demonstrates how to use the Record API routines to control a recording session. - * Although this example shows how to start and stop a recording session, it - * does NOT spawn other nodes for you. If you have no other nodes running - * which can log data, then the resulting recording will be empty. - * - */ - -#include - -#include "PolySyncNode.hpp" -#include "PolySyncRecordReplay.hpp" - - -using namespace polysync; -using namespace std; - - -// Utility function prototypes -ps_rnr_session_id getSessionIdInput(); - -void loopUntilQuitCommandReceived(); - - -/** - * @brief RecordNode class - * - * The RecordNode class exists to override the functions defined in the - * base Node class. The functions exist in the base class but - * must be overloaded to define the node's custom behavior. - */ -class RecordNode : public Node -{ - - /** - * Override the base class functionality to create and - * start a @ref polysync::RecordSession. - */ - void initStateEvent() override - { - // Create a new record session. - // Uses the @ref polysync::Node to subscribe and publish - // Record & Replay messages. - recording = new RecordSession{ *this }; - - // Set session id to value input from command line. - recording->setId( getSessionIdInput() ); - - // Activate the recording session. - recording->activate(); - - // Start the recording. - recording->start(); - - cout << "Recording started." << endl; - } - - - /** - * Override the base class functionality to end the recording after - * receiving user input. - */ - void okStateEvent() override - { - // Run until user inputs 'q' - loopUntilQuitCommandReceived(); - - // Stop the recording session. - recording->stop(); - - // Clean up dynamic memory. - delete recording; - - // Disconnect this Node. - disconnectPolySync(); - - cout << "Recording stopped." << endl; - } - - /** - * @ref polysync::RecordSession used to start and stop the - * recording session. - */ - RecordSession * recording; - -}; - -/** - * Entry point for this tutorial application. - */ -int main() -{ - // Create an instance of the RecordNode and connect it to PolySync. - RecordNode recordingNode; - - // When the node has been connected, it will call - // 'initStateEvent' once, and then continue to loop - // using 'okStateEvent' until user provides input. - recordingNode.connectPolySync(); - - return 0; -} - - -/** - * @brief Get session id value from command line input - * - * @return ps_rnr_session_id from user - */ -ps_rnr_session_id getSessionIdInput() -{ - ps_rnr_session_id sessionId; - - cout << "Enter recording session id: "; - - cin >> sessionId; - - return sessionId; -} - - -/** - * @brief Run until user inputs quit command 'q' - */ -void loopUntilQuitCommandReceived() -{ - string input; - - do - { - cout << endl << "Enter 'q' to end recording: "; - - cin >> input; - } - while( input != "q" ); -} diff --git a/Replay/CMakeLists.txt b/Replay/CMakeLists.txt deleted file mode 100644 index b51c585..0000000 --- a/Replay/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-replay-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( - ${PROJECT_NAME} - Replay.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/Replay/README.md b/Replay/README.md deleted file mode 100644 index 57124e1..0000000 --- a/Replay/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### Replay - -Replay is more of a tool than an example. It exposes much of the functionality of the ReplaySession API as a command line tool. -This is an interactive application, which expects you to enter the replay session ID and allows you to stop the replay. -As an example, this code illustrates how to properly access the RecordSession APIs functionality. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd Replay -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-replay-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/Replay/Replay.cpp b/Replay/Replay.cpp deleted file mode 100644 index 40b8813..0000000 --- a/Replay/Replay.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example Replay.cpp - * - * Demonstrates how to use the Replay API routines to control a replay session. - * Although this example shows how to start and stop a replay session, it - * does NOT spawn other nodes for you. If you have no other nodes running - * in no hardware mode which can replay log data, then the replay session - * will not replay the log file data. - */ - -#include - -#include "PolySyncNode.hpp" -#include "PolySyncRecordReplay.hpp" - - -using namespace polysync; -using namespace std; - - -// Utility function prototypes -ps_rnr_session_id getSessionIdInput(); - -void loopUntilQuitCommandReceived(); - - -/** - * @brief ReplayNode class - * - * The ReplayNode class exists to override the functions defined in the - * base Node class. The functions exist in the base class but - * must be overloaded to define the node's custom behavior. - */ -class ReplayNode : public Node -{ - - /** - * Override the base class functionality to create and - * start a @ref polysync::ReplaySession. - */ - void initStateEvent() override - { - // Create a new replay session. - // Uses the @ref polysync::Node to subscribe and publish - // Record & Replay messages. - replay = new ReplaySession{ *this }; - - // Set session id to value input from command line. - // This requires an exact value match, if incorrect value is received, restart example. - replay->setId( getSessionIdInput() ); - - // Activate the session. - replay->activate(); - - // Start the replay. - replay->start(); - - cout << "Replay started." << endl; - } - - - /** - * Override the base class functionality to end the replay session until - * the user provides some input. - */ - void okStateEvent() override - { - // Run until user inputs 'q' - loopUntilQuitCommandReceived(); - - // Stop the replay. - replay->stop(); - - // Clean up dynamic memory. - delete replay; - - // Disconnect this Node. - disconnectPolySync(); - } - - - /** - * @ref polysync::ReplaySession used to start and stop the - * replay session. - */ - ReplaySession * replay; - -}; - -/** - * Entry point for this tutorial application. - */ -int main() -{ - // Create an instance of the ReplayNode and connect it to PolySync. - ReplayNode replayNode; - - // When the node has been connected, it will call - // 'initStateEvent' once, and then call 'okStateEvent' until - // the user provides some input. - replayNode.connectPolySync(); - - return 0; -} - - -/** - * @brief Get session id value from command line input - * - * @return ps_rnr_session_id from user - */ -ps_rnr_session_id getSessionIdInput() -{ - ps_rnr_session_id sessionId; - - cout << "Enter replay session id: "; - - cin >> sessionId; - - return sessionId; -} - - -/** - * @brief Run until user inputs quit command 'q' - */ -void loopUntilQuitCommandReceived() -{ - string input; - - do - { - cout << endl << "Enter 'q' to end replay: "; - - cin >> input; - } - while( input != "q" ); -} diff --git a/SampleApplication/CMakeLists.txt b/SampleApplication/CMakeLists.txt deleted file mode 100644 index 721b207..0000000 --- a/SampleApplication/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-sample-application-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - SampleApplication.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/SampleApplication/README.md b/SampleApplication/README.md deleted file mode 100644 index 3d8f2b7..0000000 --- a/SampleApplication/README.md +++ /dev/null @@ -1,25 +0,0 @@ -### SampleApplication - -This is an example of the application node template, as opposed to the node template. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd SampleApplication -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-sample-application-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/SampleApplication/SampleApplication.cpp b/SampleApplication/SampleApplication.cpp deleted file mode 100644 index 4c6d943..0000000 --- a/SampleApplication/SampleApplication.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example SampleApplication.cpp - * - * PolySync Sample Application C++ API example application - * Demonstrate how to function as an application node - * - */ - -#include - -#include -#include -#include -#include - - -using namespace std; - - -/** - * @brief SampleApplicationNode class - * - * The SampleApplicationNode class allows the user to tap into the existing - * hooks that are implemented as part of the base Node class. The functions - * exist in the Node class but are implemented as empty function; the default - * behavior is to do nothing for a given event. - * In this sample application, we will overload all of the functions and - * explain their usage to serve as the basis for future applications. - */ -class SampleApplicationNode : public polysync::Node -{ - -public: - - /** - * The messageEvent is the hook that is called whenever an application - * receives a message from the PolySync bus. In this application - * we are sending messages that we have registered for and should receive - * them here. - */ - virtual void messageEvent( std::shared_ptr< polysync::Message > message ) - { - using namespace polysync::datamodel; - - if( auto byteArray = getSubclass< ByteArrayMessage >( message ) ) - { - byteArray->print(); - } - } - - - /** - * This function is called by PolySync when the node transitions to the - * INIT state. In this instance, we are registering for messages from the - * bus of a specific type. - * - * Other possible initialization functions include connection to a sensor - * or actuator via a bus, connection to a communication medium, opening a - * socket, etc. - */ - virtual void initStateEvent() - { - _stateIterationCount = 0; - - cout << NODE_NAME << " is initializing." << endl; - - _messageType = getMessageTypeByName( "ps_byte_array_msg" ); - - // Register as a listener for the message type that the publisher - // is going to send. Message types are defined in later tutorials. - registerListener( _messageType ); - - } - - /** - * This is called once after node transitions into the AUTH state. - * This happens near the start of program, before any PolySync related - * tasks. - * - * If this node is instantiated with argc and argv arguments they will be - * available for parsing in this function ( ie getopts ). - * - * @param [in] commandLineArgs GetOpt object containing option flags, and - * their arguments. - */ - virtual void setConfigurationEvent( const GetOpt & commandLineArgs ) - { - cout << "Printing command line data for " << NODE_NAME << endl << endl; - - // Just a display. This event is where you can handle command line input - // that make require a valid PolySync node ( ps_node_ref ). - commandLineArgs.printAll(); - } - - /** - * PolySync calls the okStateEvent frequently to minimize latency associated - * any sampling that the function might do. It is in this function that the - * the node performs most of its normal processing. If there is any sensor - * or actuator interaction, it would happen here; this is the lowest latency - * of any of the functions in a given node. - */ - void okStateEvent() - { - // In this instance, like the publisher tutorial, we will send a message - // on the bus with a sleep to minimize the loading on the bus. - - // Package and ublish a polysync::datamodel::ByteArrayMessage - publishByteArray( {'P', 'o', 'l', 'y', 'S', 'y', 'n', 'c', - ' ', 'S', 'a', 'm', 'p', 'l', 'e' } ); - - // Transition state after max iterations - if( stateHasExpired( ++_stateIterationCount ) ) - { - changeState( NODE_STATE_WARN ); - } - - // Only allow this event ot happen once per second, this prevents us - // from flooding the bus - polysync::sleepMicro( ONE_SECOND ); - } - - /** - * The fatalStateEvent event is analogous to the release event, except that - * it occurs after a fatal error has occurred. If there is anything that - * absolutely must be done (e.g. shut down a piece of hardware) before the - * node shuts down this is the place where that can be done. - */ - virtual void fatalStateEvent() - { - cout << NODE_NAME - << " received a fatal error event and will shut down." << endl; - } - - /** - * The error state event is called when a node enters an error state. There - * are a variety of ways that a node can enter this state. PolySync treats - * this very much like the @ref okStateEvent() function, calling the - * function as rapidly as possible. - * - * This function sleeps for 1 second to minimize the amount of data being - * sent to the screen. - */ - virtual void errorStateEvent() - { - cout << NODE_NAME << " is in the error state." << endl; - - polysync::sleepMicro( ONE_SECOND ); - - // Transition state after max iterations - // Note that a FATAL state shuts the node down. - if( stateHasExpired( ++_stateIterationCount ) ) - { - changeState( NODE_STATE_FATAL ); - } - } - - /** - * The warn state event is called when a node enters an error state. It is - * specifically that the node can continue to function. PolySync treats - * this very much like the @ref okStateEvent() function, calling the - * function as rapidly as possible. - * - * This function sleeps for 1 second to minimize the amount of data being - * sent to the screen. - */ - virtual void warnStateEvent() - { - // Send a warning and sleep to minimize the loading on the bus. - - // Create the message, set the time and populate the buffer and send it - publishByteArray( {'W', 'A', 'R', 'N', 'I', 'N', 'G', '!' } ); - - // Limit the number of iterations by sleeping for 1 second. - // The nominal PolySync clock is on a microsecond basis - polysync::sleepMicro( ONE_SECOND ); - - // Transition state after max iterations - if( stateHasExpired( ++_stateIterationCount ) ) - { - changeState( NODE_STATE_ERROR ); - } - } - - /** - * The release state event is called by PolySync during the normal shutdown - * sequence. This application does not require any specific functionality - * during the shutdown sequence. - */ - virtual void releaseStateEvent() - { - cout << NODE_NAME << " is shutting down." << endl; - } - - -private: - - bool stateHasExpired( uint timerTick ) - { - bool hasExpired = false; - - if( timerTick > ITERATIONS_PER_STATE ) - { - hasExpired = true; - } - - return hasExpired; - } - - void changeState( ps_node_state_kind nextState ) - { - activateFault( DTC_USAGE, nextState ); - - _stateIterationCount = 0; - } - - void publishByteArray( const std::vector< uchar > && bytes ) - { - polysync::datamodel::ByteArrayMessage message( *this ); - - message.setHeaderTimestamp( polysync::getTimestamp() ); - - message.setBytes( bytes ); - - message.publish(); - } - -public: - - static constexpr uint ITERATIONS_PER_STATE = 4; - - static constexpr auto NODE_NAME = "polysync-sample-application-cpp"; - - static constexpr ps_timestamp ONE_SECOND = 1000000; - - -private: - - /** - * The application should contain a variable that defines the type (or - * types) of messages that the application wants to receive from the - * PolySync bus. - */ - ps_msg_type _messageType; - - uint _stateIterationCount; - -}; - -/** - * Entry point for the sample application. If there are command-line arguments - * they should be handled here and used to configure the application after - * instantiation. - * - * The "connectPolySync" is a blocking call and does not return. Use Ctrl-C to - * exit. - * - * @return int - exit code - */ -int main( int argc, char * argv[] ) -{ - SampleApplicationNode sampleAppNode; - - sampleAppNode.setNodeName( SampleApplicationNode::NODE_NAME ); - - sampleAppNode.setCommandLineOptions( { argc, argv } ); - - sampleAppNode.connectPolySync(); - - return 0; -} diff --git a/SerialConfig/CMakeLists.txt b/SerialConfig/CMakeLists.txt deleted file mode 100644 index 8a30d00..0000000 --- a/SerialConfig/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-serial-config-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - SerialConfig.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/SerialConfig/README.md b/SerialConfig/README.md deleted file mode 100644 index e1ff8c6..0000000 --- a/SerialConfig/README.md +++ /dev/null @@ -1,26 +0,0 @@ -### SerialConfig - -This is an example of the Serial API used to configure a serial port. -It requires two serial ports, as the example prints strings between the two ports. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd SerialConfig -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-serial-config-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/SerialConfig/SerialConfig.cpp b/SerialConfig/SerialConfig.cpp deleted file mode 100644 index d7e46a5..0000000 --- a/SerialConfig/SerialConfig.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example SerialConfig.cpp - * - * PolySync Serial Configuration C++ API example application - * - * Demonstrate the configuration of the serial port for cases where the - * connection is using something other than no flow control, no parity, - * 8 data bits, and 1 stop bit - * - * To exercise this example requires two serial ports, they can be on the - * same computer. One of the serial ports is used by this application; - * this application sets the serial port to a 7E2 configuration. The - * other serial port should be configured the same way. The user can then - * send strings over the serial port until they send "quit" at which point - * the application will exit. - * - * Both serial ports must be capable of running at 7 Data bits, 2 Stop - * bits with even parity and support RTS/CTS hardware flow control. - */ - -#include -#include -#include -#include -#include - -using namespace std; -using namespace polysync; - -// Constant values for use in the example -const ps_datarate_kind MY_DATARATE = DATARATE_9600; -const string SERIAL_PORT( "/dev/ttyUSB0" ); -const string NODE_NAME( "polysync-serial-config-cpp" ); - -/** - * @brief SerialConfigNode class - * - * The SerialConfigNode class exists to demonstrate how to use the node class - * to perform serial read functions. - */ -class SerialConfigNode : public Node -{ -private: - Serial myDevice; - -public: - SerialConfigNode() - : myDevice( SERIAL_PORT ) - { - } - - /** - * @brief initStateEvent - * - * Initialize the serial port here - * This example will specifically set the device to use 7 data bits, 2 stop - * bits, even parity and hardware flow control using RTS/CTS - * - */ - void initStateEvent() override - { - myDevice.open(); - myDevice.setDataRate( MY_DATARATE ); - - myDevice.setDataBits( dataBits7 ); - myDevice.setStopBits( stopBits2 ); - myDevice.setParity( parityEven ); - myDevice.setHardwareFlowControl( hardwareFlowControlRtscts ); - - myDevice.applySettings(); - } - - /** - * @brief okStateEvent - * - * Perform a read here and process any data that has been read. - * This requires an external device configured to the same serial - * configuration to communicate. Any messages sent over that connection - * will be printed unless the user sends "quit" at which point the program - * will exit. - * - */ - void okStateEvent() override - { - vector< uchar > readBuffer; - ps_timestamp ts; - - // Returns the number of bytes read. - myDevice.read( readBuffer, ts ); - - string command; - - for ( unsigned int i = 0; i < readBuffer.size(); i++ ) - { - command.push_back( static_cast( readBuffer[i] ) ); - } - - if ( command == "quit" ) - { - disconnectPolySync(); - } - else - { - // User is free to add their own commands here - cout << "Received the following command: " << command << endl; - } - } - - /** - * @brief releaseStateEvent - * - * Perform the serial port cleanup here. - * When the user sends the "quit" command the node executes the release - * state at which point the program resets the serial port back to N,8,1 - * with no flow control - * - */ - void releaseStateEvent() override - { - myDevice.setDataBits( dataBits8 ); - myDevice.setStopBits( stopBits1 ); - myDevice.setParity( parityNone ); - myDevice.setHardwareFlowControl( hardwareFlowControlNone ); - - myDevice.applySettings(); - - myDevice.close(); - } - -}; - -/** - * @brief main - * - * The "connectPolySync" function begins the node's PolySync execution loop. - * - * @return int - exit code - */ -int main() -{ - - try - { - // Create an instance of the SerialConfigNode and connect it to PolySync - SerialConfigNode SerialConfigNode; - SerialConfigNode.setNodeName(NODE_NAME); - SerialConfigNode.connectPolySync(); - } - catch( polysync::DTCException & e ) - { - std::cout << e.what() << std::endl; - } - - return 0; -} diff --git a/SerialReader/CMakeLists.txt b/SerialReader/CMakeLists.txt deleted file mode 100644 index c7e2b34..0000000 --- a/SerialReader/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-serial-reader-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - SerialReader.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/SerialReader/README.md b/SerialReader/README.md deleted file mode 100644 index f60912e..0000000 --- a/SerialReader/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### SerialReader - -This can be used as a reference if a node is required to listen to a device over a serial connection. -This example creates and reads data through a serial connection to a hardware device, or another software application. -It exercises the Serial API and pairs nicely with the `SerialWriter` example. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd SerialReader -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-serial-reader-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/SerialReader/SerialReader.cpp b/SerialReader/SerialReader.cpp deleted file mode 100644 index 3917bd2..0000000 --- a/SerialReader/SerialReader.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example SerialReader.cpp - * - * PolySync Serial Reader C++ API example application - * Demonstrate the user of a serial reader node - */ - -#include -#include -#include -#include -#include - -using namespace std; - -// Constant values for use in the example -const ps_datarate_kind MY_DATARATE = DATARATE_9600; -const string SERIAL_PORT( "/dev/ttyUSB0" ); -const string NODE_NAME( "polysync-serial-reader-cpp" ); - -/** - * @brief SerialReaderNode class - * - * The SerialReaderNode class exists to demonstrate how to use the node class - * to perform serial read functions. - */ -class SerialReaderNode : public polysync::Node -{ -private: - polysync::Serial myDevice; - -public: - SerialReaderNode() - : myDevice( SERIAL_PORT ) - { - } - - /** - * @brief initStateEvent - * - * Initialize the serial port here - * - */ - void initStateEvent() override - { - myDevice.open(); - myDevice.setDataRate( MY_DATARATE ); - myDevice.applySettings(); - } - - /** - * @brief okStateEvent - * - * Perform a read here and process any data that has been read. - * - */ - void okStateEvent() override - { - vector< uchar > readBuffer; - ps_timestamp ts; - - // Returns number of bytes read. - myDevice.read( readBuffer, ts ); - - // Up to the user on what to do with the data here. - // Options include: print it, consume it, publish it, transform it... - } - - /** - * @brief releaseStateEvent - * - * Perform the serial port cleanup here. - * - */ - void releaseStateEvent() override - { - myDevice.close(); - } - -}; - -/** - * @brief main - * - * The "connectPolySync" function begins the node's PolySync execution loop. - * - * @return int - exit code - */ -int main() -{ - - try - { - // Create an instance of the SerialReaderNode and connect it to PolySync - SerialReaderNode serialReaderNode; - serialReaderNode.setNodeName(NODE_NAME); - serialReaderNode.connectPolySync(); - } - catch( polysync::DTCException & e ) - { - std::cout << e.what() << std::endl; - } - - return 0; -} diff --git a/SerialWriter/CMakeLists.txt b/SerialWriter/CMakeLists.txt deleted file mode 100644 index d035ac3..0000000 --- a/SerialWriter/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8.11 ) - -project( polysync-serial-writer-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - SerialWriter.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/SerialWriter/README.md b/SerialWriter/README.md deleted file mode 100644 index 0a7820a..0000000 --- a/SerialWriter/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### SerialWriter - -This can be used as a reference if a node is required to speak directly to a device over a serial connection. -It pairs nicely with the `SerialReader` example. -This example creates and writes data to a serial connection, to a hardware device, or to another software application. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd SerialWriter -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-serial-writer-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/SerialWriter/SerialWriter.cpp b/SerialWriter/SerialWriter.cpp deleted file mode 100644 index e978afe..0000000 --- a/SerialWriter/SerialWriter.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example SerialWriter.cpp - * - * PolySync Serial Writer C++ API example application - * Demonstrate the user of a serial writer node - */ - -#include -#include -#include -#include - -using namespace std; - -// Constant values for use in the example -const ps_datarate_kind MY_DATARATE = DATARATE_9600; -const string SERIAL_PORT( "/dev/ttyUSB0" ); -const string NODE_NAME( "polysync-serial-writer-cpp" ); - -/** - * @brief SerialWriterNode class - * - * The SerialWriterNode class exists to demonstrate how to use the node class - * to perform serial write functions. - */ -class SerialWriterNode : public polysync::Node -{ -private: - polysync::Serial myDevice; - -public: - SerialWriterNode() - : myDevice( SERIAL_PORT ) - { - } - - /** - * @brief initStateEvent - * - * Initialize the serial port here - * - */ - void initStateEvent() override - { - myDevice.open(); - myDevice.setDataRate( MY_DATARATE ); - myDevice.applySettings(); - } - - /** - * @brief okStateEvent - * - * Perform a read here and process any data that has been read. - * - */ - void okStateEvent() override - { - vector< uchar > writeBuffer; - - writeBuffer.resize( NODE_NAME.size() + 1, 0 ); - - memcpy(writeBuffer.data(), NODE_NAME.data(), NODE_NAME.size() ); - - // Returns number of bytes written. - myDevice.write( writeBuffer ); - - // Up to the user on what to do with the data here. - // Options include: print it, consume it, publish it, transform it... - } - - /** - * @brief releaseStateEvent - * - * Perform the serial port cleanup here. - * - */ - void releaseStateEvent() override - { - myDevice.close(); - } - -}; - -/** - * @brief main - * - * The "connectPolySync" function begins the node's PolySync execution loop. - * - * @return int - exit code - */ -int main() -{ - // Create an instance of the SerialReaderNode and connect it to PolySync - SerialWriterNode serialWriterNode; - serialWriterNode.setNodeName(NODE_NAME); - serialWriterNode.connectPolySync(); - - return 0; -} diff --git a/SharedMemoryImageDataViewer/CMakeLists.txt b/SharedMemoryImageDataViewer/CMakeLists.txt deleted file mode 100644 index 2eaa55d..0000000 --- a/SharedMemoryImageDataViewer/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-sharedmem-image-data-viewer-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -set( CMAKE_INCLUDE_CURRENT_DIR ON ) -set( CMAKE_AUTOMOC ON ) - -find_package( Qt5Widgets ) - -add_executable( ${PROJECT_NAME} - SharedMemoryImageDataViewer.cpp - VideoViewer.cpp - VideoProcessor.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} - Qt5::Widgets -) diff --git a/SharedMemoryImageDataViewer/README.md b/SharedMemoryImageDataViewer/README.md deleted file mode 100644 index ce1b4e0..0000000 --- a/SharedMemoryImageDataViewer/README.md +++ /dev/null @@ -1,37 +0,0 @@ -### SharedMemoryImageDataViewer - -This code is an example application that demonstrates using the PolySync Shared Memory C++ API. This can be used to read, encode, decode, and view data placed in shared memory by a video device driver writing to shared memory using the PolySync Shared Memory API in C++. - -You must set up the shared memory queue buffer size prior to starting the application. -It requires RGB24 pixel format. - -### Hardware requirements - -Sensors: LiDAR, RADAR -Video Device - -### Dependencies - -A system installation of Qt is required for this to compile. -Qt operates under [LGPLv3](http://www.gnu.org/licenses/lgpl-3.0.en.html). -Download and install Qt [here](http://www.qt.io/download/). - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -```` - -### Building and running the node - -```bash -$ cd SharedMemoryImageDataViewer -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-sharedmem-image-data-viewer-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/SharedMemoryImageDataViewer/SharedMemoryImageDataViewer.cpp b/SharedMemoryImageDataViewer/SharedMemoryImageDataViewer.cpp deleted file mode 100644 index f8908cf..0000000 --- a/SharedMemoryImageDataViewer/SharedMemoryImageDataViewer.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example SharedMemoryImageDataViewer.cpp - * - * PolySync Sample C++ API example - * Demonstrate access to shared memory written to by a video device driver. - * - * In order to compile and run: - * - * 1.) Example requires PolySync Lochsa (v2.0) or later. - * - * 2.) Make sure to set up a video device using the polysync-sdf-configurator - * tool. - * - * 3.) In the SDF configurator, under "IO Configuration" for the device, set - * "Shared Memory Output Queue Key to a unique key that you will input to - * this example. - * - * 4.) Run your device driver. "polysync-dynamic-driver -n 1 -o" Assuming your driver's - * identifier is 1 in the system design file. - * - * 5.) To build this example, starting in it's directory: - * 1 - mkdir build && cd build - * 2 - cmake .. - * 3 - make .. - * - * 6.) Run the example: - * 1 - ./polysync-shdmem-image-data-viewer-cpp - */ -#include -#include -#include - -#include "VideoProcessor.hpp" -#include "VideoViewer.hpp" - -#include -#include - -using namespace std; - -int main( int argc, char *argv[] ) -{ - // Object required to execute Qt GUI functionality - QApplication app( argc, argv ); - - auto videoProcessor = - std::unique_ptr< VideoProcessor >( new VideoProcessor ); - - // Check for shared memory key argument - if( argc > 1 ) - { - try - { - videoProcessor.get()->_sharedMemoryKey = std::stoul( argv[ 1 ] ); - } - catch( std::exception & e ) - { - std::cout << "Invalid memory key. This example requires valid " - "integer input representing a shared memory key." - << std::endl - << "For example: " - "polysync-shdmem-image-data-viewer-cpp 12345" - << std::endl; - - return 1; - } - } - else - { - std::cout << "Must pass executable a sharedMemoryKey" << std::endl; - std::cout << "See the Knowledge Base article: \n" - "(https://support.harbrick.com/hc/en-us/articles/217046318-Connecting-to-a-Sensor-Webcam)\n" - " to configure video device to operate in shared memory mode." - << std::endl; - return 1; - } - - // Thread video processing loop, this will continously pull data from - // a video device and send a QPixmap to the VideoViewer object for rendering. - QThread * processingThread = new QThread; - videoProcessor->moveToThread( processingThread ); - processingThread->start(); - - auto videoViewer = std::unique_ptr< VideoViewer >( new VideoViewer ); - - // Qt signal/slot connect for passing data between processor and viewer. - QObject::connect( videoProcessor.get(), &VideoProcessor::signalPixmap, - videoViewer.get(), &VideoViewer::slotUpdatePixmap ); - - // Start processing in one millisecond, this allows for the next line of - // code to be called, spawning the Qt application context. - QTimer::singleShot( 1/*ms*/, videoProcessor.get(), - SLOT( slotRun() ) ); - - // Blocking loop until the Viewer widget is closed. - int appReturn = app.exec(); - - // Halt thread execution and release dynamic memory - processingThread->requestInterruption(); - processingThread->deleteLater(); - - return appReturn; -} diff --git a/SharedMemoryImageDataViewer/VideoProcessor.cpp b/SharedMemoryImageDataViewer/VideoProcessor.cpp deleted file mode 100644 index e60c02d..0000000 --- a/SharedMemoryImageDataViewer/VideoProcessor.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "VideoProcessor.hpp" - -#include -#include -#include - -#include -#include - -#include - -using namespace std; - -void VideoProcessor::slotRun() -{ - // Set the desired format for video device. - polysync::VideoFormat deviceFormat{ - PIXEL_FORMAT_YUYV, - 640, 480, - PSYNC_VIDEO_DEFAULT_FRAMES_PER_SECOND }; - - // Set format for encoder output - polysync::VideoFormat encodedFormat{ - PIXEL_FORMAT_H264, - 640, 480, - PSYNC_VIDEO_DEFAULT_FRAMES_PER_SECOND }; - - // Set format for decoder output - polysync::VideoFormat decodedFormat{ - PIXEL_FORMAT_BGR24, - 640, - 480, - PSYNC_VIDEO_DEFAULT_FRAMES_PER_SECOND }; - - try - { - polysync::SharedMemoryImageData sharedMemory( _sharedMemoryKey ); - - // Attach to existing shared memory segment at given key - sharedMemory.attach(); - - // Set size of input data buffer to arbitrarily large size - sharedMemory.setBufferSize( 1280*1080*3 ); - - // Create encoder/decoder - polysync::VideoEncoder encoder{ deviceFormat, encodedFormat }; - polysync::VideoDecoder decoder{ encodedFormat, decodedFormat }; - - while( 1 ) - { - // Block and wait for data - // Shared memory behaves as a FIFO (first in, first out ) queue. - sharedMemory.pop(); - - if( sharedMemory.getMessageType() == PSYNC_SHDMEM_MSG_TYPE_IMAGE_DATA ) - { - // Encode data received - encoder.encode( sharedMemory.getData() ); - - auto encodedBuffer = encoder.getCopyOfEncodedBuffer(); - auto encodedSize = encodedBuffer.size(); - - if( encodedSize > 0 ) - { - // Decode encoded data - decoder.decode( encodedBuffer ); - auto decodedBuffer = decoder.getCopyOfDecodedBuffer(); - - auto decodedSize = decodedBuffer.size(); - if( decodedSize > 0 ) - { - QImage img( decodedBuffer.data(), - 640, 480, - QImage::Format_RGB888 ); - - // Output data to VideoViewer for rendering - emit signalPixmap( QPixmap::fromImage( img ) ); - } - } - } - } - } - catch( polysync::DTCException & e ) - { - cout << e.what() << endl; - } -} diff --git a/SharedMemoryImageDataViewer/VideoProcessor.hpp b/SharedMemoryImageDataViewer/VideoProcessor.hpp deleted file mode 100644 index 8d295e2..0000000 --- a/SharedMemoryImageDataViewer/VideoProcessor.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef VIDEOPROCESSOR_H -#define VIDEOPROCESSOR_H - -#include -#include - -#include - -/** - * @brief The VideoProcessor class - * This class attempts to access a shared memory segment created by an - * image device driver. - * - * @note Use polysync-sdf-configurator to add a device. In the device's IO, set - * the shared memory key. This will tell the driver to open a shared memory - * segment and write data to it. Make sure that the key you pass in when running - * the example matches the key in your SDF. - */ -class VideoProcessor : public QObject -{ - // Qt Macro allowing for signals/slots - Q_OBJECT - -public: - - /** - * @brief sharedMemoryKey - * Key used to access existing shared memory segment created by device. - */ - ulong _sharedMemoryKey{ 0 }; - -public slots: - - /** - * @brief slotRun - * Contains the busy loop which polls video device for frames, packages - * the data into a QPixmap, and sends to the VideoViewer object for - * rendering. - */ - void slotRun(); - -signals: - - /** - * @brief signalPixmap - * Qt Signal emitted when new data is ready for rendering. This triggers - * @ref VideoViewer::slotUpdatePixmap, passing the new QPixmap to draw. - */ - void signalPixmap( const QPixmap & ); -}; -#endif // VIDEOPROCESSOR_H diff --git a/SharedMemoryImageDataViewer/VideoViewer.cpp b/SharedMemoryImageDataViewer/VideoViewer.cpp deleted file mode 100644 index f33fec0..0000000 --- a/SharedMemoryImageDataViewer/VideoViewer.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "VideoViewer.hpp" - -#include -#include -#include - - -VideoViewer::VideoViewer() - : - _layout( new QHBoxLayout( this ) ), - _label( new QLabel( this ) ) -{ - // Set viewing window to an appropriate size. - resize( 640, 480 ); - - // Add layout element to this widget. - setLayout( _layout ); - _label = new QLabel( this ); - - // Add label to this widget. The label contains the QPixmap that we update. - _layout->addWidget( _label ); - - // Make this widget/window visible on screen. - show(); -} - -void VideoViewer::slotUpdatePixmap( const QPixmap &pixmap ) -{ - // Update the view - _label->setPixmap( pixmap ); -} diff --git a/SharedMemoryImageDataViewer/VideoViewer.hpp b/SharedMemoryImageDataViewer/VideoViewer.hpp deleted file mode 100644 index 6b398c4..0000000 --- a/SharedMemoryImageDataViewer/VideoViewer.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef VIDEOVIEWER_H -#define VIDEOVIEWER_H - -#include - -class QPixmap; -class QHBoxLayout; -class QLabel; - -/** - * @brief The VideoViewer class - * The class inherits from QWidget and contains elements necessary to view - * a video frame. - */ -class VideoViewer : public QWidget -{ - // Qt Macro enabling Qt signals and slots - Q_OBJECT - -public: - - /** - * @brief VideoViewer ctor - * Allocates resources for @ref _label and @ref _layout, then adds them - * to this widget. Calls QWidget::show() to make the widget appear on - * screen. - */ - VideoViewer(); - -public slots: - - /** - * @brief slotUpdatePixmap - * Triggered from VideoProcessor when new data is available to render. - * @param [in] pixmap Updated pixmap to render on @ref _label. - */ - void slotUpdatePixmap( const QPixmap & pixmap ); - -private: - /** @{ GUI Elements */ - QHBoxLayout * _layout{ nullptr }; - QLabel * _label{ nullptr }; - /** @} */ -}; - - -#endif // VIDEOVIEWER_H diff --git a/SingleTransform/CMakeLists.txt b/SingleTransform/CMakeLists.txt deleted file mode 100644 index 848a16d..0000000 --- a/SingleTransform/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-single-transform-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - SingleTransform.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/SingleTransform/README.md b/SingleTransform/README.md deleted file mode 100644 index 07bad46..0000000 --- a/SingleTransform/README.md +++ /dev/null @@ -1,26 +0,0 @@ -### SingleTransform - -This example demonstrates PolySync transform API usage. -It pushes a transform to the stack, and then shows the resulting transformation. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd SingleTransform -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-single-transform-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/SingleTransform/SingleTransform.cpp b/SingleTransform/SingleTransform.cpp deleted file mode 100644 index c0a4676..0000000 --- a/SingleTransform/SingleTransform.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example SingleTransform.cpp - * - * Transform Example in C++ to demonstrate a single level transform. - * - * Shows how to use the transform API to perform a single operation on the - * transform stack. - * - * - * Transform Class definition - * file:///usr/local/polysync/doc/cpp_api_docs/html/d9/d32/classpolysync_1_1_transform.html - */ - -#include - -#include -#include - -using namespace polysync; - -int main() -{ - // The transform object can throw one of several DTC errors for a given function call. - // This is a large try-catch block to describe where the error occurred. - try - { - // Create a Transform object, an origin, and an orientation - Transform transform; - - // Set the origin using an array of doubles that contain the X,Y,Z - // coordinates of the origin - transform.setOrigin( { 0.0, 0.0, 0.0 } ); - - // Set the orientation using an array of doubles that contain the - // roll, pitch, yaw, of the transform - transform.setOrientation( { 1.0, 2.0, 3.0 } ); - - // Push the transform on to the transform stack using the ps_identifier - // PSYNC_COORDINATE_FRAME_PLATFORM - transform.push( PSYNC_COORDINATE_FRAME_PLATFORM ); - - // Apply the entire transformation from the start to the end point - auto endPoint = transform.apply( { 3.3, 2.2, 1.1 } ); - - // Display the results of the transform - std::cout << "Starting position: " - << 3.3 - << ", " - << 2.2 - << ", " - << 1.1 - << std::endl; - std::cout << "Ending position: " << endPoint[P_X] << ", "; - std::cout << endPoint[P_Y] << ", "; - std::cout << endPoint[P_Z] << std::endl; - - } - catch ( polysync::DTCException& d ) - { - std::cout << "The example encountered the following error: " - << d.what() - << std::endl; - } - - return 0; -} - diff --git a/SocketReader/CMakeLists.txt b/SocketReader/CMakeLists.txt deleted file mode 100644 index d2cf5cd..0000000 --- a/SocketReader/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-socket-reader-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - SocketReader.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/SocketReader/README.md b/SocketReader/README.md deleted file mode 100644 index b8951c3..0000000 --- a/SocketReader/README.md +++ /dev/null @@ -1,26 +0,0 @@ -### SocketReader - -This is a simple example illustrating UDP socket communication in PolySync when using the PolySync socket API. -It reads from the UDP socket using API calls and socket class. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd SocketReader -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-socket-reader-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/SocketReader/SocketReader.cpp b/SocketReader/SocketReader.cpp deleted file mode 100644 index 90c28ff..0000000 --- a/SocketReader/SocketReader.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example SocketReader.cpp - * - * PolySync SocketReader C++ API example application - * Connect to a UDP socket and receive data - */ - -#include - -#include -#include -#include - - -// set socket re-use enabled flag -#define ENABLED 1 - - -using namespace std; - -const int SOCKET_DOMAIN = AF_INET; -const int SOCKET_PROTOCOL = IPPROTO_UDP; -const int SOCKET_TYPE = SOCK_DGRAM; -const string NODE_NAME( "polysync-socket-reader-cpp" ); - -/** - * @brief SocketReaderNode class - * - * The SocketReaderNode class exists to demonstrate how to use the node class - * to perform UDP socker read functions. - */ -class SocketReaderNode : public polysync::Node -{ -private: - polysync::Socket mySocket; - -public: - SocketReaderNode() - : mySocket( SOCKET_DOMAIN, SOCKET_TYPE, SOCKET_PROTOCOL ) - { - } - - /** - * @brief initStateEvent - * - * Initialize the socket here - * - */ - void initStateEvent() override - { - // connect to (localhost) - std::string ipAddr = "127.0.0.1"; - - // copy from string into the vector of char - const std::vector< char > addr( ipAddr.begin(), ipAddr.end() ); - - ulong port = 1197; - - // set the address and port for our object and bind to the socket - mySocket.setAddress( addr, port ); - - // set socket reuse option for multiple connections - mySocket.setReuse( ENABLED ); - mySocket.bind(); - - // connect to the socket - mySocket.connect(); - } - - /** - * @brief okStateEvent - * - * Perform a read here and process any data that has been read. - * - */ - void okStateEvent() override - { - vector< uchar > receiveBuffer; - ps_timestamp timestamp; - - // Returns number of bytes received. - mySocket.receive( receiveBuffer, timestamp ); - - // Up to the user on what to do with the data here. - // Options include: print it, consume it, publish it, transform it... - } - - /** - * @brief releaseStateEvent - * - * Perform the socket cleanup here. - * - */ - void releaseStateEvent() override - { - mySocket.release(); - } - -}; - -/** - * @brief main - * - * The "connectPolySync" function begins the node's PolySync execution loop. - * - * @return int - exit code - */ -int main() -{ - // Create an instance of the SocketReaderNode and connect it to PolySync - SocketReaderNode socketReaderNode; - socketReaderNode.setNodeName(NODE_NAME); - socketReaderNode.connectPolySync(); - - return 0; -} - diff --git a/SocketWriter/CMakeLists.txt b/SocketWriter/CMakeLists.txt deleted file mode 100644 index 6ef2c06..0000000 --- a/SocketWriter/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-socket-writer-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - SocketWriter.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/SocketWriter/README.md b/SocketWriter/README.md deleted file mode 100644 index 44dc784..0000000 --- a/SocketWriter/README.md +++ /dev/null @@ -1,26 +0,0 @@ -### SocketWriter - -This is a simple example illustrating UDP socket communication in PolySync when using the PolySync socket API. -It writes from UDP socket using API calls and socket class. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd SocketWriter -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-socket-writer-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/SocketWriter/SocketWriter.cpp b/SocketWriter/SocketWriter.cpp deleted file mode 100644 index f3d2f3d..0000000 --- a/SocketWriter/SocketWriter.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example SocketWriter.cpp - * - * PolySync SocketWriter C++ API example application - * Connect to a UDP socket and send data - */ - -#include - -#include -#include -#include - -// set socket re-use enabled flag -#define ENABLED 1 - -using namespace std; - -const int SOCKET_DOMAIN = AF_INET; -const int SOCKET_PROTOCOL = IPPROTO_UDP; -const int SOCKET_TYPE = SOCK_DGRAM; -const string NODE_NAME( "polysync-socket-writer-cpp" ); - -/** - * @brief SocketWriterNode class - * - * The SocketWriterNode class exists to demonstrate how to use the node class - * to perform UDP socket write functions. - */ -class SocketWriterNode : public polysync::Node -{ -private: - polysync::Socket mySocket; - - -public: - SocketWriterNode() - : mySocket( SOCKET_DOMAIN, SOCKET_TYPE, SOCKET_PROTOCOL ) - { - } - - /** - * @brief initStateEvent - * - * Initialize the socket here - * - */ - void initStateEvent() override - { - // connect to (localhost) - const vector< char > addr { 127, 0, 0, 1 }; - - ulong port = 1197; - - // set the address and port for our object and bind to the socket - mySocket.setAddress( addr, port ); - - // set socket reuse option for multiple connections - mySocket.setReuse( ENABLED ); - mySocket.bind(); - - // connect to the socket - mySocket.connect(); - } - - /** - * @brief okStateEvent - * - * Perform a write to localhost here. - * - */ - void okStateEvent() override - { - vector< uchar > sendBuffer - { 'S', 'o', 'c', 'k', 'e', 't', ' ', 'W', 'r', 'i', 't', 'e', 'r' }; - - // returns number of bytes sent - mySocket.send( sendBuffer ); - } - - /** - * @brief releaseStateEvent - * - * Perform the socket cleanup here. - * - */ - void releaseStateEvent() override - { - mySocket.release(); - } - -}; - -/** - * @brief main - * - * The "connectPolySync" function begins the node's PolySync execution loop. - * - * @return int - exit code - */ -int main() -{ - // Create an instance of the SocketWriterNode and connect it to PolySync - SocketWriterNode socketWriterNode; - socketWriterNode.setNodeName(NODE_NAME); - socketWriterNode.connectPolySync(); - - return 0; -} - - diff --git a/TransformStack/CMakeLists.txt b/TransformStack/CMakeLists.txt deleted file mode 100644 index 63dc94f..0000000 --- a/TransformStack/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-transform-stack-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -add_executable( ${PROJECT_NAME} - TransformStack.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/TransformStack/README.md b/TransformStack/README.md deleted file mode 100644 index f1a5323..0000000 --- a/TransformStack/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### TransformStack - -This example illustrates how to use the transform API to perform multiple transforms in the same stack. -It demonstrates PolySync transform API usage. -It pushes a transform to the stack. - -### Dependencies - -Packages: libglib2.0-dev - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev -``` - -### Building and running the node - -```bash -$ cd TransformStack -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-transform-stack-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/TransformStack/TransformStack.cpp b/TransformStack/TransformStack.cpp deleted file mode 100644 index 8a8fdad..0000000 --- a/TransformStack/TransformStack.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example TransformStack.cpp - * - * Transform Example to demonstrate a transform stack. - * - * Shows how to use the transform API to perform multiple transforms in the - * same stack. The transforms can incorporate changes in orientation and - * spatial location e.g. the object is spinning while moving forward. - * - * Transform Class definition - */ - -#include - -#include -#include - -using namespace polysync; - -int main() -{ - // The transform object can throw one of several DTC errors for a given - // function call. This is a large try-catch block to describe where the - // error occurred. - try - { - // Create a Transform object, an origin, and an orientation - Transform transform; - - // Variable to store identifiers in the transform stack - ps_identifier id = PSYNC_COORDINATE_FRAME_PLATFORM; - - // The first transform is strictly a scalar in space. - // There is no change in orientation. - - // Set the origin (10,0,0) - transform.setOrigin( { 10.0, 0.0, 0.0 } ); - - // Set the orientation - transform.setOrientation( { 0.0, 0.0, 0.0 } ); - - // Push the transform on to the transform stack using the ps_identifier - // PSYNC_COORDINATE_FRAME_PLATFORM - transform.push( id ); - - // The second stage of the transform involves both a change in the - // origin and a change in orientation. - // Transform moves to the right and rotates around the z-axis - transform.setOrigin( { 0.0, -10, 0.0 } ); - transform.setOrientation( { 0.0, 0.0, 2.0 } ); - - // Increment ID so that the next push has a unique ID - id++; - transform.push( id ); - - // Apply the entire transformation from the start to the end point - std::array< double, 3 > startPt = { 1.0, 1.0, 1.0 }; - - auto endPt = transform.apply( startPt ); - - // Display the results of the transform - std::cout << "Starting position: " << startPt[P_X] << ", " - << startPt[P_Y] << ", " << startPt[P_Z] << std::endl; - - std::cout << "Ending position: " << endPt[P_X] << ", " << endPt[P_Y]; - std::cout << ", " << endPt[P_Z] << std::endl; - - } - catch ( polysync::DTCException& d ) - { - std::cout << "polysync-transform-stack-cpp encountered the following error: " - << d.what() << std::endl; - } - - return 0; -} - diff --git a/VideoDeviceViewer/CMakeLists.txt b/VideoDeviceViewer/CMakeLists.txt deleted file mode 100644 index 520c04b..0000000 --- a/VideoDeviceViewer/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-video-device-viewer-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) - -set( CMAKE_INCLUDE_CURRENT_DIR ON ) -set( CMAKE_AUTOMOC ON ) - -find_package( Qt5Widgets ) - -add_executable( ${PROJECT_NAME} - main.cpp - VideoViewer.cpp - VideoProcessor.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} - Qt5::Widgets -) diff --git a/VideoDeviceViewer/README.md b/VideoDeviceViewer/README.md deleted file mode 100644 index 5581f9a..0000000 --- a/VideoDeviceViewer/README.md +++ /dev/null @@ -1,38 +0,0 @@ -### VideoDeviceViewer - -This code is an example application to demonstrate interaction with a video device using the PolySync Video API in C++. -It will visualize LiDAR, RADAR, and object data from multiple sources. -This example has tools to freeze frame and measure distance, color by source or type, and is great for building sensor fusion applications. -The graphics were built with OpenGL and are very extendable. -It has a built-in system/node management tool to dynamically handle nodes coming on/off bus. - -### Hardware requirements - -Sensors: LiDAR, RADAR -Video Device - -### Dependencies - -A system installation of Qt is required for this to compile. -Qt operates under [LGPLv3](http://www.gnu.org/licenses/lgpl-3.0.en.html). -Download and install Qt [here](http://www.qt.io/download/). - -Packages: libglib2.0-dev libgstreamer1.0-0 - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev libgstreamer1.0-0 -``` - -### Building and running the node - -```bash -$ cd VideoDeviceViewer -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-video-device-viewer-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/VideoDeviceViewer/VideoProcessor.cpp b/VideoDeviceViewer/VideoProcessor.cpp deleted file mode 100644 index 9eeef7d..0000000 --- a/VideoDeviceViewer/VideoProcessor.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "VideoProcessor.hpp" - -#include -#include - -#include -#include - -#include - -using namespace std; - -void VideoProcessor::slotRun() -{ - // Set the desired format for video device. - polysync::VideoFormat deviceFormat{ - PIXEL_FORMAT_MJPEG, - 640, 480, - PSYNC_VIDEO_DEFAULT_FRAMES_PER_SECOND }; - - try - { - // Search system for possible devices - auto videoDeviceList = polysync::getAvailableVideoDevices(); - - if( videoDeviceList.size() > 0 ) - { - // Grab the first available device, likely /dev/video0 in Linux. - auto videoDevice = videoDeviceList[ 0 ]; - - // Make sure the device supports our desired format - if( ! videoDevice.formatIsSupported( deviceFormat ) ) - { - return; - } - - videoDevice.setFormat( deviceFormat ); - - videoDevice.enableStreaming(); - - // Continously pull data from the device while it's available. - while( videoDevice.poll() ) - { - auto frame = videoDevice.getFrame(); - - emit signalPixmap( QPixmap::fromImage( - QImage::fromData( - frame.data(), - frame.size() ) ) ); - } - } - } - catch( polysync::DTCException & e ) - { - cout << e.what() << endl; - } -} diff --git a/VideoDeviceViewer/VideoProcessor.hpp b/VideoDeviceViewer/VideoProcessor.hpp deleted file mode 100644 index 9bfc687..0000000 --- a/VideoDeviceViewer/VideoProcessor.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef VIDEOPROCESSOR_H -#define VIDEOPROCESSOR_H - -#include -#include - -#include - -/** - * @brief The VideoProcessor class - * This class is responsible for interaction with a video device using the - * PolySyncVideo API. It attempts to open the first available video device on - * the system. In Linux, this is often /dev/video0. On a laptop, this will - * likely be the webcam. On a desktop machine, a video device will need to be - * connected, typically via USB. - */ -class VideoProcessor : public QObject -{ - // Qt Macro allowing for signals/slots - Q_OBJECT - -public slots: - - /** - * @brief slotRun - * Contains the busy loop which polls video device for frames, packages - * the data into a QPixmap, and sends to the VideoViewer object for - * rendering. - */ - void slotRun(); - -signals: - - /** - * @brief signalPixmap - * Qt Signal emitted when new data is ready for rendering. This triggers - * @ref VideoViewer::slotUpdatePixmap, passing the new QPixmap to draw. - */ - void signalPixmap( const QPixmap & ); -}; -#endif // VIDEOPROCESSOR_H diff --git a/VideoDeviceViewer/VideoViewer.cpp b/VideoDeviceViewer/VideoViewer.cpp deleted file mode 100644 index 16b7812..0000000 --- a/VideoDeviceViewer/VideoViewer.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "VideoViewer.hpp" - -#include -#include -#include - - -VideoViewer::VideoViewer() - : - _layout( new QHBoxLayout( this ) ), - _label( new QLabel( this ) ) -{ - // Set viewing window to an appropriate size. - resize( 640, 480 ); - - // Add layout element to this widget. - setLayout( _layout ); - _label = new QLabel( this ); - - // Add label to this widget. The label contains the QPixmap that we update. - _layout->addWidget( _label ); - - // Make this widget/window visible on screen. - show(); -} - -void VideoViewer::slotUpdatePixmap( const QPixmap &pixmap ) -{ - // Update the view - _label->setPixmap( pixmap ); -} diff --git a/VideoDeviceViewer/VideoViewer.hpp b/VideoDeviceViewer/VideoViewer.hpp deleted file mode 100644 index 0b9c9bf..0000000 --- a/VideoDeviceViewer/VideoViewer.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef VIDEOVIEWER_H -#define VIDEOVIEWER_H - -#include - -class QPixmap; -class QHBoxLayout; -class QLabel; - -/** - * @brief The VideoViewer class - * The class inherits from QWidget and contains elements necessary to view - * a video frame. - */ -class VideoViewer : public QWidget -{ - // Qt Macro enabling Qt signals and slots - Q_OBJECT - -public: - - /** - * @brief VideoViewer ctor - * Allocates resources for @ref _label and @ref _layout, then adds them - * to this widget. Calls QWidget::show() to make the widget appear on - * screen. - */ - VideoViewer(); - -public slots: - - /** - * @brief slotUpdatePixmap - * Triggered from VideoProcessor when new data is available to render. - * @param [in] pixmap Updated pixmap to render on @ref _label. - */ - void slotUpdatePixmap( const QPixmap & pixmap ); - -private: - /** @{ GUI Elements */ - QHBoxLayout * _layout{ nullptr }; - QLabel * _label{ nullptr }; - /** @} */ -}; - - -#endif // VIDEOVIEWER_H diff --git a/VideoDeviceViewer/main.cpp b/VideoDeviceViewer/main.cpp deleted file mode 100644 index 1285e53..0000000 --- a/VideoDeviceViewer/main.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include - -#include "VideoProcessor.hpp" -#include "VideoViewer.hpp" - -#include - -using namespace std; - -int main( int argc, char *argv[] ) -{ - // Object required to execute Qt GUI functionality - QApplication app( argc, argv ); - - auto videoProcessor = - std::unique_ptr< VideoProcessor >( new VideoProcessor ); - - // Thread video processing loop, this will continously pull data from - // a video device and send a QPixmap to the VideoViewer object for rendering. - QThread * processingThread = new QThread; - videoProcessor->moveToThread( processingThread ); - processingThread->start(); - - auto videoViewer = - std::unique_ptr< VideoViewer >( new VideoViewer ); - - // Qt signal/slot connect for passing data between processor and viewer. - QObject::connect( videoProcessor.get(), &VideoProcessor::signalPixmap, - videoViewer.get(), &VideoViewer::slotUpdatePixmap ); - - // Start processing in one millisecond, this allows for the next line of - // code to be called, spawning the Qt application context. - QTimer::singleShot( 1/*ms*/, videoProcessor.get(), SLOT( slotRun() ) ); - - // Blocking loop until the Viewer widget is closed. - int appReturn = app.exec(); - - // Halt thread execution and release dynamic memory - processingThread->requestInterruption(); - processingThread->deleteLater(); - - return appReturn; -} diff --git a/VideoEncodeDecode/CMakeLists.txt b/VideoEncodeDecode/CMakeLists.txt deleted file mode 100644 index 70cd89e..0000000 --- a/VideoEncodeDecode/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -cmake_minimum_required( VERSION 2.8 ) - -project( polysync-video-encode-decode-cpp ) - -if( NOT PSYNC_HOME ) - if( $ENV{PSYNC_HOME} ) - set( PSYNC_HOME $ENV{PSYNC_HOME} ) - else() - set( PSYNC_HOME /usr/local/polysync ) - endif() -endif() - -include( ${PSYNC_HOME}/BuildResources.cmake ) - -include_directories( - ${PSYNC_INCLUDE_DIRS} -) -add_executable( ${PROJECT_NAME} - VideoEncodeDecode.cpp -) - -target_link_libraries( ${PROJECT_NAME} - ${PSYNC_LIBS} -) diff --git a/VideoEncodeDecode/README.md b/VideoEncodeDecode/README.md deleted file mode 100644 index d656f23..0000000 --- a/VideoEncodeDecode/README.md +++ /dev/null @@ -1,35 +0,0 @@ -### VideoEncodeDecode - -This example demonstrates how to use the Video API routines to communicate with a video device, and encode/decode the data. - -You would use this example if you needed a node to talk directly to a video device, and didn’t want to use the `generic-video-device` driver, which supports all V4L USB video devices. -It connects to a USB webcam (that must be Video4Linux (V4L) compatible), encodes the sensor data, and then decodes the same image stream to show the image processing pipeline. -This DOES NOT connect to a node defined in the SDF, it connects directly to the hardware device using the Video API. -It expects XXXXX pixel format - -### Hardware requirements - -Sensors: LiDAR, RADAR -Video Device - -### Dependencies - -Packages: libglib2.0-dev libgstreamer1.0-0 - -To install on Ubuntu: - -```bash -sudo apt-get install libglib2.0-dev libgstreamer1.0-0 -``` - -### Building and running the node - -```bash -$ cd VideoDeviceViewer -$ mkdir build && cd build -$ cmake .. -$ make -$ ./polysync-video-encode-decode-cpp -``` - -For more API examples, visit the "Tutorials" and "Development" sections in the PolySync Help Center [here](https://help.polysync.io/articles/). diff --git a/VideoEncodeDecode/VideoEncodeDecode.cpp b/VideoEncodeDecode/VideoEncodeDecode.cpp deleted file mode 100644 index c9c6133..0000000 --- a/VideoEncodeDecode/VideoEncodeDecode.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2016 PolySync - * - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/** - * \example VideoEncodeDecode.cpp - * - * Shows how to use the Video API routines to communicate with a video device, - * and encode/decode the data. - * - */ - -#include - -#include - -using namespace std; - -int main() -{ - // Set the desired format for video device. - polysync::VideoFormat deviceFormat{ - PIXEL_FORMAT_YUYV, - 640, 480, - PSYNC_VIDEO_DEFAULT_FRAMES_PER_SECOND }; - - // Set format for encoder output - polysync::VideoFormat encodedFormat{ - PIXEL_FORMAT_H264, - 640, 480, - PSYNC_VIDEO_DEFAULT_FRAMES_PER_SECOND }; - - // Set format for decoder output - polysync::VideoFormat decodedFormat{ - PIXEL_FORMAT_RGB24, - 640, - 480, - PSYNC_VIDEO_DEFAULT_FRAMES_PER_SECOND }; - - // Create encoder/decoder - polysync::VideoEncoder encoder{ deviceFormat, encodedFormat }; - polysync::VideoDecoder decoder{ encodedFormat, decodedFormat }; - - try - { - // Search system for possible devices - auto videoDeviceList = polysync::getAvailableVideoDevices(); - - if( videoDeviceList.size() > 0 ) - { - // Grab the first available device, likely /dev/video0 in Linux. - auto videoDevice = videoDeviceList[ 0 ]; - - // Make sure the device supports our desired format - if( ! videoDevice.formatIsSupported( deviceFormat ) ) - { - cout << "VideoFormat not supported." << endl; - - return 0; - } - - videoDevice.setFormat( deviceFormat ); - - videoDevice.enableStreaming(); - - ulong frameIndex{ 0 }; - - // Pull data from device - while( videoDevice.poll() ) - { - cout << "Frame[ " << frameIndex << " ]: " << endl; - - cout << " Raw Size: " << videoDevice.getFrameSize() << endl; - - // Compress frame - encoder.encode( videoDevice.getFrame() ); - auto encodedBuffer = encoder.getCopyOfEncodedBuffer(); - auto encodedSize = encodedBuffer.size(); - - if( encodedSize > 0 ) - { - cout << " Encoded size: " << encodedSize << endl; - - decoder.decode( encodedBuffer ); - auto decodedBuffer = decoder.getCopyOfDecodedBuffer(); - - auto decodedSize = decodedBuffer.size(); - if( decodedSize > 0 ) - { - cout << " Decoded size: " << decodedSize << endl; - - ++frameIndex; - } - } - } - } - } - catch( std::exception & e ) - { - cout << e.what() << endl; - } -}